{"id":379,"date":"2024-11-17T11:49:15","date_gmt":"2024-11-17T10:49:15","guid":{"rendered":"https:\/\/www.systemdeveloper.nl\/tech\/?p=379"},"modified":"2024-11-17T11:49:16","modified_gmt":"2024-11-17T10:49:16","slug":"from-chaos-to-clarity-modular-api-design-in-python","status":"publish","type":"post","link":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/","title":{"rendered":"From Chaos to Clarity: Modular API Design in Python"},"content":{"rendered":"<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">APIs are a cornerstone of modern software, but as they grow, their complexity can spiral out of control. What starts as a straightforward script quickly evolves into a tangled web of functions, routes, and hard-coded logic. We&#8217;ve been there. Today, we&rsquo;re sharing how we transformed our monitoring API from a monolithic script into a modular, scalable, and production-ready application&mdash;powered by Flask and Gunicorn.<\/p>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Whether you&#8217;re developing your first API or improving an existing one, our journey provides valuable lessons, pitfalls to avoid, and actionable code examples.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"the-challenge-a-growing-api\"><strong>The Challenge: A Growing API<\/strong><\/h3>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Initially, <a href=\"\/tech\/building-a-secure-configurable-and-scalable-monitoring-api\/\">our API<\/a> began as a single Python script. It served its purpose well&mdash;receiving monitoring data, writing to an InfluxDB, and performing validation. But as features like API key validation, server registration, and dynamic field configuration were added, the code became difficult to maintain.<\/p>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Key issues we faced:<\/p>\n\n\n<ul class=\"wp-block-list wp-block-list\">\n<li>\n<strong>Maintenance headaches<\/strong>: All routes and logic lived in one file, making debugging a nightmare.<\/li>\n\n\n\n<li>\n<strong>Scalability concerns<\/strong>: The default Flask server isn&#8217;t suited for handling production-level traffic.<\/li>\n\n\n\n<li>\n<strong>Flexibility<\/strong>: Adding new endpoints often required altering core logic, introducing potential regressions.<\/li>\n<\/ul>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">We needed a cleaner, more scalable design.<\/p>\n\n\n<h3 class=\"wp-block-heading\" id=\"our-solution-modular-api-architecture\"><strong>Our Solution: Modular API Architecture<\/strong><\/h3>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">We tackled the problem by re-architecting the API with three key principles:<\/p>\n\n\n<ol class=\"wp-block-list wp-block-list\">\n<li>\n<strong>Separation of concerns<\/strong>: Split routes, database functions, and application configuration into distinct modules.<\/li>\n\n\n\n<li>\n<strong>Blueprints for organization<\/strong>: Use Flask Blueprints to group related routes.<\/li>\n\n\n\n<li>\n<strong>Production-ready server<\/strong>: Deploy the API under Gunicorn, a WSGI server designed for scalable applications.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<h3 class=\"wp-block-heading\" id=\"the-modular-structure\"><strong>The Modular Structure<\/strong><\/h3>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Our new structure looks like this:<\/p>\n\n\n<pre class=\"wp-block-code\"><div class=\"copy-to-clipboard\">\n<span>Copied!<\/span><button class=\"click-to-copy-button\" title=\"Copy to clipboard\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 32 32\" stroke=\"currentcolor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"24\" height=\"24\" fill=\"none\">\n  <path d=\"M12.9975 10.7499L11.7475 10.7499C10.6429 10.7499 9.74747 11.6453 9.74747 12.7499L9.74747 21.2499C9.74747 22.3544 10.6429 23.2499 11.7475 23.2499L20.2475 23.2499C21.352 23.2499 22.2475 22.3544 22.2475 21.2499L22.2475 12.7499C22.2475 11.6453 21.352 10.7499 20.2475 10.7499L18.9975 10.7499Z\"><\/path>\n  <path d=\"M17.9975 12.2499L13.9975 12.2499C13.4452 12.2499 12.9975 11.8022 12.9975 11.2499L12.9975 9.74988C12.9975 9.19759 13.4452 8.74988 13.9975 8.74988L17.9975 8.74988C18.5498 8.74988 18.9975 9.19759 18.9975 9.74988L18.9975 11.2499C18.9975 11.8022 18.5498 12.2499 17.9975 12.2499Z\"><\/path>\n  <path d=\"M13.7475 16.2499L18.2475 16.2499\"><\/path>\n  <path d=\"M13.7475 19.2499L18.2475 19.2499\"><\/path>\n<\/svg><\/button><textarea>monapi\/\n&#9474;\n&#9500;&#9472;&#9472; app\/\n&#9474;   &#9500;&#9472;&#9472; __init__.py           # App factory\n&#9474;   &#9500;&#9472;&#9472; routes\/               # Flask Blueprints\n&#9474;   &#9474;   &#9500;&#9472;&#9472; data.py           # Handles data submission\n&#9474;   &#9474;   &#9500;&#9472;&#9472; servers.py        # Server management\n&#9474;   &#9474;   &#9500;&#9472;&#9472; fields.py         # Field configuration\n&#9474;   &#9474;   &#9492;&#9472;&#9472; agent.py          # Agent-specific endpoints\n&#9474;   &#9500;&#9472;&#9472; db\/                   # Database functions\n&#9474;   &#9474;   &#9500;&#9472;&#9472; influxdb.py       # InfluxDB-related functions\n&#9474;   &#9474;   &#9500;&#9472;&#9472; sqlite.py         # SQLite helper functions\n&#9474;   &#9492;&#9472;&#9472; config.py             # Centralized configurations\n&#9474;\n&#9500;&#9472;&#9472; config.db                 # SQLite database\n&#9500;&#9472;&#9472; wsgi.py                   # Gunicorn entry point\n&#9500;&#9472;&#9472; requirements.txt          # Python dependencies\n&#9492;&#9472;&#9472; README.md<\/textarea>\n<\/div><code>monapi\/\n&#9474;\n&#9500;&#9472;&#9472; app\/\n&#9474;   &#9500;&#9472;&#9472; __init__.py           # App factory\n&#9474;   &#9500;&#9472;&#9472; routes\/               # Flask Blueprints\n&#9474;   &#9474;   &#9500;&#9472;&#9472; data.py           # Handles data submission\n&#9474;   &#9474;   &#9500;&#9472;&#9472; servers.py        # Server management\n&#9474;   &#9474;   &#9500;&#9472;&#9472; fields.py         # Field configuration\n&#9474;   &#9474;   &#9492;&#9472;&#9472; agent.py          # Agent-specific endpoints\n&#9474;   &#9500;&#9472;&#9472; db\/                   # Database functions\n&#9474;   &#9474;   &#9500;&#9472;&#9472; influxdb.py       # InfluxDB-related functions\n&#9474;   &#9474;   &#9500;&#9472;&#9472; sqlite.py         # SQLite helper functions\n&#9474;   &#9492;&#9472;&#9472; config.py             # Centralized configurations\n&#9474;\n&#9500;&#9472;&#9472; config.db                 # SQLite database\n&#9500;&#9472;&#9472; wsgi.py                   # Gunicorn entry point\n&#9500;&#9472;&#9472; requirements.txt          # Python dependencies\n&#9492;&#9472;&#9472; README.md<\/code><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"code-walkthrough\"><strong>Code Walkthrough<\/strong><\/h3>\n\n\n<h4 class=\"wp-block-heading\" id=\"app-factory-init-py\"><strong>App Factory (<code>__init__.py<\/code>)<\/strong><\/h4>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">The app factory initializes the Flask app and registers Blueprints.<\/p>\n\n\n<pre class=\"wp-block-code\"><div class=\"copy-to-clipboard\">\n<span>Copied!<\/span><button class=\"click-to-copy-button\" title=\"Copy to clipboard\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 32 32\" stroke=\"currentcolor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"24\" height=\"24\" fill=\"none\">\n  <path d=\"M12.9975 10.7499L11.7475 10.7499C10.6429 10.7499 9.74747 11.6453 9.74747 12.7499L9.74747 21.2499C9.74747 22.3544 10.6429 23.2499 11.7475 23.2499L20.2475 23.2499C21.352 23.2499 22.2475 22.3544 22.2475 21.2499L22.2475 12.7499C22.2475 11.6453 21.352 10.7499 20.2475 10.7499L18.9975 10.7499Z\"><\/path>\n  <path d=\"M17.9975 12.2499L13.9975 12.2499C13.4452 12.2499 12.9975 11.8022 12.9975 11.2499L12.9975 9.74988C12.9975 9.19759 13.4452 8.74988 13.9975 8.74988L17.9975 8.74988C18.5498 8.74988 18.9975 9.19759 18.9975 9.74988L18.9975 11.2499C18.9975 11.8022 18.5498 12.2499 17.9975 12.2499Z\"><\/path>\n  <path d=\"M13.7475 16.2499L18.2475 16.2499\"><\/path>\n  <path d=\"M13.7475 19.2499L18.2475 19.2499\"><\/path>\n<\/svg><\/button><textarea>from flask import Flask\nfrom app.routes import data, servers, fields, agent\n\ndef create_app():\n    app = Flask(__name__)\n\n    # Register Blueprints\n    app.register_blueprint(data.bp)\n    app.register_blueprint(servers.bp)\n    app.register_blueprint(fields.bp)\n    app.register_blueprint(agent.bp)\n\n    return app<\/textarea>\n<\/div><code>from flask import Flask\nfrom app.routes import data, servers, fields, agent\n\ndef create_app():\n    app = Flask(__name__)\n\n    # Register Blueprints\n    app.register_blueprint(data.bp)\n    app.register_blueprint(servers.bp)\n    app.register_blueprint(fields.bp)\n    app.register_blueprint(agent.bp)\n\n    return app<\/code><\/pre>\n\n\n<h4 class=\"wp-block-heading\" id=\"endpoints-with-blueprints\"><strong>Endpoints with Blueprints<\/strong><\/h4>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Blueprints allow us to group related functionality. For example, here&rsquo;s the <code>register_server<\/code> endpoint from <code>servers.py<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\"><div class=\"copy-to-clipboard\">\n<span>Copied!<\/span><button class=\"click-to-copy-button\" title=\"Copy to clipboard\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 32 32\" stroke=\"currentcolor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"24\" height=\"24\" fill=\"none\">\n  <path d=\"M12.9975 10.7499L11.7475 10.7499C10.6429 10.7499 9.74747 11.6453 9.74747 12.7499L9.74747 21.2499C9.74747 22.3544 10.6429 23.2499 11.7475 23.2499L20.2475 23.2499C21.352 23.2499 22.2475 22.3544 22.2475 21.2499L22.2475 12.7499C22.2475 11.6453 21.352 10.7499 20.2475 10.7499L18.9975 10.7499Z\"><\/path>\n  <path d=\"M17.9975 12.2499L13.9975 12.2499C13.4452 12.2499 12.9975 11.8022 12.9975 11.2499L12.9975 9.74988C12.9975 9.19759 13.4452 8.74988 13.9975 8.74988L17.9975 8.74988C18.5498 8.74988 18.9975 9.19759 18.9975 9.74988L18.9975 11.2499C18.9975 11.8022 18.5498 12.2499 17.9975 12.2499Z\"><\/path>\n  <path d=\"M13.7475 16.2499L18.2475 16.2499\"><\/path>\n  <path d=\"M13.7475 19.2499L18.2475 19.2499\"><\/path>\n<\/svg><\/button><textarea>from flask import Blueprint, request, jsonify\nfrom app.db.sqlite import db_register_server\n\nbp = Blueprint('servers', __name__)\n\n@bp.route('\/api\/register_server', methods=['POST'])\ndef register_server():\n    hostname = request.json.get('hostname')\n    ip_address = request.json.get('ip_address')\n\n    if not hostname or not ip_address:\n        return jsonify({\"error\": \"Hostname and IP address are required\"}), 400\n\n    try:\n        api_key = db_register_server(hostname, ip_address)\n        return jsonify({\"status\": \"success\", \"hostname\": hostname, \"ip_address\": ip_address, \"api_key\": api_key}), 201\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500<\/textarea>\n<\/div><code>from flask import Blueprint, request, jsonify\nfrom app.db.sqlite import db_register_server\n\nbp = Blueprint('servers', __name__)\n\n@bp.route('\/api\/register_server', methods=['POST'])\ndef register_server():\n    hostname = request.json.get('hostname')\n    ip_address = request.json.get('ip_address')\n\n    if not hostname or not ip_address:\n        return jsonify({\"error\": \"Hostname and IP address are required\"}), 400\n\n    try:\n        api_key = db_register_server(hostname, ip_address)\n        return jsonify({\"status\": \"success\", \"hostname\": hostname, \"ip_address\": ip_address, \"api_key\": api_key}), 201\n    except Exception as e:\n        return jsonify({\"error\": str(e)}), 500<\/code><\/pre>\n\n\n<h4 class=\"wp-block-heading\" id=\"database-logic-in-sqlite-py\"><strong>Database Logic in <code>sqlite.py<\/code><\/strong><\/h4>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Database operations are abstracted into functions for reusability:<\/p>\n\n\n<pre class=\"wp-block-code\"><div class=\"copy-to-clipboard\">\n<span>Copied!<\/span><button class=\"click-to-copy-button\" title=\"Copy to clipboard\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 32 32\" stroke=\"currentcolor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"24\" height=\"24\" fill=\"none\">\n  <path d=\"M12.9975 10.7499L11.7475 10.7499C10.6429 10.7499 9.74747 11.6453 9.74747 12.7499L9.74747 21.2499C9.74747 22.3544 10.6429 23.2499 11.7475 23.2499L20.2475 23.2499C21.352 23.2499 22.2475 22.3544 22.2475 21.2499L22.2475 12.7499C22.2475 11.6453 21.352 10.7499 20.2475 10.7499L18.9975 10.7499Z\"><\/path>\n  <path d=\"M17.9975 12.2499L13.9975 12.2499C13.4452 12.2499 12.9975 11.8022 12.9975 11.2499L12.9975 9.74988C12.9975 9.19759 13.4452 8.74988 13.9975 8.74988L17.9975 8.74988C18.5498 8.74988 18.9975 9.19759 18.9975 9.74988L18.9975 11.2499C18.9975 11.8022 18.5498 12.2499 17.9975 12.2499Z\"><\/path>\n  <path d=\"M13.7475 16.2499L18.2475 16.2499\"><\/path>\n  <path d=\"M13.7475 19.2499L18.2475 19.2499\"><\/path>\n<\/svg><\/button><textarea>import sqlite3\nimport uuid\n\nCONFIG_DB_PATH = 'config.db'\n\ndef db_register_server(hostname, ip_address):\n    api_key = str(uuid.uuid4())\n\n    conn = sqlite3.connect(CONFIG_DB_PATH)\n    cursor = conn.cursor()\n    try:\n        cursor.execute(\"\"\"\n            INSERT INTO servers (hostname, ip_address, api_key)\n            VALUES (?, ?, ?)\n        \"\"\", (hostname, ip_address, api_key))\n        conn.commit()\n        return api_key\n    finally:\n        conn.close()<\/textarea>\n<\/div><code>import sqlite3\nimport uuid\n\nCONFIG_DB_PATH = 'config.db'\n\ndef db_register_server(hostname, ip_address):\n    api_key = str(uuid.uuid4())\n\n    conn = sqlite3.connect(CONFIG_DB_PATH)\n    cursor = conn.cursor()\n    try:\n        cursor.execute(\"\"\"\n            INSERT INTO servers (hostname, ip_address, api_key)\n            VALUES (?, ?, ?)\n        \"\"\", (hostname, ip_address, api_key))\n        conn.commit()\n        return api_key\n    finally:\n        conn.close()<\/code><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"deploying-with-gunicorn\"><strong>Deploying with Gunicorn<\/strong><\/h3>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Gunicorn provides a production-grade WSGI server. Here&rsquo;s how we configured it:<br>Install Gunicorn:<\/p>\n\n\n<ol class=\"wp-block-list wp-block-list\"><\/ol>\n\n\n<pre class=\"wp-block-code\"><div class=\"copy-to-clipboard\">\n<span>Copied!<\/span><button class=\"click-to-copy-button\" title=\"Copy to clipboard\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 32 32\" stroke=\"currentcolor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"24\" height=\"24\" fill=\"none\">\n  <path d=\"M12.9975 10.7499L11.7475 10.7499C10.6429 10.7499 9.74747 11.6453 9.74747 12.7499L9.74747 21.2499C9.74747 22.3544 10.6429 23.2499 11.7475 23.2499L20.2475 23.2499C21.352 23.2499 22.2475 22.3544 22.2475 21.2499L22.2475 12.7499C22.2475 11.6453 21.352 10.7499 20.2475 10.7499L18.9975 10.7499Z\"><\/path>\n  <path d=\"M17.9975 12.2499L13.9975 12.2499C13.4452 12.2499 12.9975 11.8022 12.9975 11.2499L12.9975 9.74988C12.9975 9.19759 13.4452 8.74988 13.9975 8.74988L17.9975 8.74988C18.5498 8.74988 18.9975 9.19759 18.9975 9.74988L18.9975 11.2499C18.9975 11.8022 18.5498 12.2499 17.9975 12.2499Z\"><\/path>\n  <path d=\"M13.7475 16.2499L18.2475 16.2499\"><\/path>\n  <path d=\"M13.7475 19.2499L18.2475 19.2499\"><\/path>\n<\/svg><\/button><textarea>pip install gunicorn<\/textarea>\n<\/div><code>pip install gunicorn<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Create a <code>wsgi.py<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\"><div class=\"copy-to-clipboard\">\n<span>Copied!<\/span><button class=\"click-to-copy-button\" title=\"Copy to clipboard\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 32 32\" stroke=\"currentcolor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"24\" height=\"24\" fill=\"none\">\n  <path d=\"M12.9975 10.7499L11.7475 10.7499C10.6429 10.7499 9.74747 11.6453 9.74747 12.7499L9.74747 21.2499C9.74747 22.3544 10.6429 23.2499 11.7475 23.2499L20.2475 23.2499C21.352 23.2499 22.2475 22.3544 22.2475 21.2499L22.2475 12.7499C22.2475 11.6453 21.352 10.7499 20.2475 10.7499L18.9975 10.7499Z\"><\/path>\n  <path d=\"M17.9975 12.2499L13.9975 12.2499C13.4452 12.2499 12.9975 11.8022 12.9975 11.2499L12.9975 9.74988C12.9975 9.19759 13.4452 8.74988 13.9975 8.74988L17.9975 8.74988C18.5498 8.74988 18.9975 9.19759 18.9975 9.74988L18.9975 11.2499C18.9975 11.8022 18.5498 12.2499 17.9975 12.2499Z\"><\/path>\n  <path d=\"M13.7475 16.2499L18.2475 16.2499\"><\/path>\n  <path d=\"M13.7475 19.2499L18.2475 19.2499\"><\/path>\n<\/svg><\/button><textarea>from app import create_app\n\napp = create_app()<\/textarea>\n<\/div><code>from app import create_app\n\napp = create_app()<\/code><\/pre>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">Run Gunicorn:<\/p>\n\n\n<pre class=\"wp-block-code\"><div class=\"copy-to-clipboard\">\n<span>Copied!<\/span><button class=\"click-to-copy-button\" title=\"Copy to clipboard\"><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewbox=\"0 0 32 32\" stroke=\"currentcolor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" width=\"24\" height=\"24\" fill=\"none\">\n  <path d=\"M12.9975 10.7499L11.7475 10.7499C10.6429 10.7499 9.74747 11.6453 9.74747 12.7499L9.74747 21.2499C9.74747 22.3544 10.6429 23.2499 11.7475 23.2499L20.2475 23.2499C21.352 23.2499 22.2475 22.3544 22.2475 21.2499L22.2475 12.7499C22.2475 11.6453 21.352 10.7499 20.2475 10.7499L18.9975 10.7499Z\"><\/path>\n  <path d=\"M17.9975 12.2499L13.9975 12.2499C13.4452 12.2499 12.9975 11.8022 12.9975 11.2499L12.9975 9.74988C12.9975 9.19759 13.4452 8.74988 13.9975 8.74988L17.9975 8.74988C18.5498 8.74988 18.9975 9.19759 18.9975 9.74988L18.9975 11.2499C18.9975 11.8022 18.5498 12.2499 17.9975 12.2499Z\"><\/path>\n  <path d=\"M13.7475 16.2499L18.2475 16.2499\"><\/path>\n  <path d=\"M13.7475 19.2499L18.2475 19.2499\"><\/path>\n<\/svg><\/button><textarea>gunicorn -w 4 -b 0.0.0.0:5000 wsgi:app<\/textarea>\n<\/div><code>gunicorn -w 4 -b 0.0.0.0:5000 wsgi:app<\/code><\/pre>\n\n\n<h3 class=\"wp-block-heading\" id=\"results-and-learnings\"><strong>Results and Learnings<\/strong><\/h3>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">By adopting this modular approach:<\/p>\n\n\n<ul class=\"wp-block-list wp-block-list\">\n<li>\n<strong>Maintainability<\/strong>: Each module focuses on a single concern, making the codebase easier to understand and modify.<\/li>\n\n\n\n<li>\n<strong>Scalability<\/strong>: With Gunicorn, the API can handle multiple concurrent requests.<\/li>\n\n\n\n<li>\n<strong>Flexibility<\/strong>: Adding new endpoints or modifying existing ones is straightforward.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\">The modular redesign of our API has not only improved its performance but also made it a joy to work on. Whether you&#8217;re building APIs for monitoring, analytics, or any other purpose, investing time in a clean architecture pays off.<\/p>\n\n\n<p class=\"wp-block-paragraph wp-block-paragraph\" style=\"\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>APIs are a cornerstone of modern software, but as they grow, their complexity can spiral out of control. What starts as a straightforward script quickly evolves into a tangled web of functions, routes, and hard-coded logic. We&#8217;ve been there. Today, we&rsquo;re sharing how we transformed our monitoring API from a monolithic script into a modular, &hellip;<\/p>\n","protected":false},"author":1,"featured_media":380,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46,16],"tags":[15,37],"class_list":["post-379","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-howto","category-tech-innovation","tag-api","tag-monitoring"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>From Chaos to Clarity: Modular API Design in Python - SystemDeveloper.NL<\/title>\n<meta name=\"description\" content=\"Today, we\u2019re sharing how we transformed our monitoring API from a monolithic script into a production-ready application\u2014powered by Flask and Gunicorn.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"From Chaos to Clarity: Modular API Design in Python - SystemDeveloper.NL\" \/>\n<meta property=\"og:description\" content=\"Today, we\u2019re sharing how we transformed our monitoring API from a monolithic script into a production-ready application\u2014powered by Flask and Gunicorn.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/\" \/>\n<meta property=\"og:site_name\" content=\"SystemDeveloper.NL\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/quan.tora.16\" \/>\n<meta property=\"article:published_time\" content=\"2024-11-17T10:49:15+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-11-17T10:49:16+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1024\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/webp\" \/>\n<meta name=\"author\" content=\"John Timmer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"John Timmer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"2 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/\"},\"author\":{\"name\":\"John Timmer\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#\\\/schema\\\/person\\\/5760c2ed5300c56d8ef01dfb00a9763b\"},\"headline\":\"From Chaos to Clarity: Modular API Design in Python\",\"datePublished\":\"2024-11-17T10:49:15+00:00\",\"dateModified\":\"2024-11-17T10:49:16+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/\"},\"wordCount\":411,\"publisher\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp\",\"keywords\":[\"API\",\"Monitoring\"],\"articleSection\":[\"Howto\",\"Tech Innovation\"],\"inLanguage\":\"en\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/\",\"url\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/\",\"name\":\"From Chaos to Clarity: Modular API Design in Python - SystemDeveloper.NL\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp\",\"datePublished\":\"2024-11-17T10:49:15+00:00\",\"dateModified\":\"2024-11-17T10:49:16+00:00\",\"description\":\"Today, we\u2019re sharing how we transformed our monitoring API from a monolithic script into a production-ready application\u2014powered by Flask and Gunicorn.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/#breadcrumb\"},\"inLanguage\":\"en\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp\",\"contentUrl\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp\",\"width\":1024,\"height\":768,\"caption\":\"From Chaos to Clarity: Modular API Design for Scalable Monitoring Systems\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/from-chaos-to-clarity-modular-api-design-in-python\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"From Chaos to Clarity: Modular API Design in Python\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#website\",\"url\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/\",\"name\":\"www.systemdeveloper.nl\",\"description\":\"NextGen IT\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#organization\",\"name\":\"www.systemdeveloper.nl\",\"url\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/qt-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/qt-logo.png\",\"width\":1346,\"height\":1230,\"caption\":\"www.systemdeveloper.nl\"},\"image\":{\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/quan.tora.16\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/#\\\/schema\\\/person\\\/5760c2ed5300c56d8ef01dfb00a9763b\",\"name\":\"John Timmer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en\",\"@id\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/cropped-D6E27035-6864-4270-8D72-0D8C0C59F370-96x96.jpeg\",\"url\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/cropped-D6E27035-6864-4270-8D72-0D8C0C59F370-96x96.jpeg\",\"contentUrl\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/wp-content\\\/uploads\\\/2024\\\/11\\\/cropped-D6E27035-6864-4270-8D72-0D8C0C59F370-96x96.jpeg\",\"caption\":\"John Timmer\"},\"sameAs\":[\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\"],\"url\":\"https:\\\/\\\/www.systemdeveloper.nl\\\/tech\\\/author\\\/admin\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"From Chaos to Clarity: Modular API Design in Python - SystemDeveloper.NL","description":"Today, we\u2019re sharing how we transformed our monitoring API from a monolithic script into a production-ready application\u2014powered by Flask and Gunicorn.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/","og_locale":"en_US","og_type":"article","og_title":"From Chaos to Clarity: Modular API Design in Python - SystemDeveloper.NL","og_description":"Today, we\u2019re sharing how we transformed our monitoring API from a monolithic script into a production-ready application\u2014powered by Flask and Gunicorn.","og_url":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/","og_site_name":"SystemDeveloper.NL","article_publisher":"https:\/\/www.facebook.com\/quan.tora.16","article_published_time":"2024-11-17T10:49:15+00:00","article_modified_time":"2024-11-17T10:49:16+00:00","og_image":[{"width":1024,"height":768,"url":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp","type":"image\/webp"}],"author":"John Timmer","twitter_card":"summary_large_image","twitter_misc":{"Written by":"John Timmer","Est. reading time":"2 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/#article","isPartOf":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/"},"author":{"name":"John Timmer","@id":"https:\/\/www.systemdeveloper.nl\/tech\/#\/schema\/person\/5760c2ed5300c56d8ef01dfb00a9763b"},"headline":"From Chaos to Clarity: Modular API Design in Python","datePublished":"2024-11-17T10:49:15+00:00","dateModified":"2024-11-17T10:49:16+00:00","mainEntityOfPage":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/"},"wordCount":411,"publisher":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/#organization"},"image":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp","keywords":["API","Monitoring"],"articleSection":["Howto","Tech Innovation"],"inLanguage":"en"},{"@type":"WebPage","@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/","url":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/","name":"From Chaos to Clarity: Modular API Design in Python - SystemDeveloper.NL","isPartOf":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/#primaryimage"},"image":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/#primaryimage"},"thumbnailUrl":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp","datePublished":"2024-11-17T10:49:15+00:00","dateModified":"2024-11-17T10:49:16+00:00","description":"Today, we\u2019re sharing how we transformed our monitoring API from a monolithic script into a production-ready application\u2014powered by Flask and Gunicorn.","breadcrumb":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/#breadcrumb"},"inLanguage":"en","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/"]}]},{"@type":"ImageObject","inLanguage":"en","@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/#primaryimage","url":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp","contentUrl":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/79f4e730-e5fb-414f-9d13-9862ff9ba434-e1731840400791.webp","width":1024,"height":768,"caption":"From Chaos to Clarity: Modular API Design for Scalable Monitoring Systems"},{"@type":"BreadcrumbList","@id":"https:\/\/www.systemdeveloper.nl\/tech\/from-chaos-to-clarity-modular-api-design-in-python\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.systemdeveloper.nl\/tech\/"},{"@type":"ListItem","position":2,"name":"From Chaos to Clarity: Modular API Design in Python"}]},{"@type":"WebSite","@id":"https:\/\/www.systemdeveloper.nl\/tech\/#website","url":"https:\/\/www.systemdeveloper.nl\/tech\/","name":"www.systemdeveloper.nl","description":"NextGen IT","publisher":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.systemdeveloper.nl\/tech\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en"},{"@type":"Organization","@id":"https:\/\/www.systemdeveloper.nl\/tech\/#organization","name":"www.systemdeveloper.nl","url":"https:\/\/www.systemdeveloper.nl\/tech\/","logo":{"@type":"ImageObject","inLanguage":"en","@id":"https:\/\/www.systemdeveloper.nl\/tech\/#\/schema\/logo\/image\/","url":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/qt-logo.png","contentUrl":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/qt-logo.png","width":1346,"height":1230,"caption":"www.systemdeveloper.nl"},"image":{"@id":"https:\/\/www.systemdeveloper.nl\/tech\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/quan.tora.16"]},{"@type":"Person","@id":"https:\/\/www.systemdeveloper.nl\/tech\/#\/schema\/person\/5760c2ed5300c56d8ef01dfb00a9763b","name":"John Timmer","image":{"@type":"ImageObject","inLanguage":"en","@id":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/cropped-D6E27035-6864-4270-8D72-0D8C0C59F370-96x96.jpeg","url":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/cropped-D6E27035-6864-4270-8D72-0D8C0C59F370-96x96.jpeg","contentUrl":"https:\/\/www.systemdeveloper.nl\/tech\/wp-content\/uploads\/2024\/11\/cropped-D6E27035-6864-4270-8D72-0D8C0C59F370-96x96.jpeg","caption":"John Timmer"},"sameAs":["https:\/\/www.systemdeveloper.nl\/tech"],"url":"https:\/\/www.systemdeveloper.nl\/tech\/author\/admin\/"}]}},"_links":{"self":[{"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/posts\/379","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/comments?post=379"}],"version-history":[{"count":1,"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/posts\/379\/revisions"}],"predecessor-version":[{"id":381,"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/posts\/379\/revisions\/381"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/media\/380"}],"wp:attachment":[{"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/media?parent=379"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/categories?post=379"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.systemdeveloper.nl\/tech\/wp-json\/wp\/v2\/tags?post=379"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}