<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Bruno Enrique ANCCO SUAÑA</title>
    <description>The latest articles on Forem by Bruno Enrique ANCCO SUAÑA (@brunoenr).</description>
    <link>https://forem.com/brunoenr</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3069500%2F021133c8-068d-4066-879c-03afefd66454.png</url>
      <title>Forem: Bruno Enrique ANCCO SUAÑA</title>
      <link>https://forem.com/brunoenr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/brunoenr"/>
    <language>en</language>
    <item>
      <title>🔌The Magic of MCP Servers: Unlocking Infinite Context for AI</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Wed, 26 Nov 2025 04:41:12 +0000</pubDate>
      <link>https://forem.com/brunoenr/the-magic-of-mcp-servers-unlocking-infinite-context-for-ai-40i1</link>
      <guid>https://forem.com/brunoenr/the-magic-of-mcp-servers-unlocking-infinite-context-for-ai-40i1</guid>
      <description>&lt;h2&gt;
  
  
  🚀 What is an MCP Server?
&lt;/h2&gt;

&lt;p&gt;Think of an MCP Server as a "Universal Translator" between your data and AI models.&lt;br&gt;
In the past, if you wanted an AI to use a specific tool (like checking a Jira ticket), you had to build a custom integration just for that AI. If you switched AIs, you had to rebuild it.&lt;/p&gt;

&lt;p&gt;With MCP:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You build an MCP Server once.&lt;/li&gt;
&lt;li&gt;It exposes your data (Resources), actions (Tools), and templates (Prompts).&lt;/li&gt;
&lt;li&gt;Any MCP-compliant client can connect to it instantly&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🤝 Connects to Any Client
&lt;/h2&gt;

&lt;p&gt;The beauty of this protocol is its interoperability. An MCP Server doesn't care who is asking for the data, as long as they speak "MCP".&lt;/p&gt;

&lt;p&gt;Supported Clients include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Desktop App: Connects locally to read your files or query databases while you chat.&lt;/li&gt;
&lt;li&gt;VS Code (with Extensions): Allows your IDE to "see" external documentation or server logs to help you code better.&lt;/li&gt;
&lt;li&gt;Zed Editor: Fast, AI-powered coding that leverages your custom MCP tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🛠️ How It Works Under the Hood
&lt;/h2&gt;

&lt;p&gt;The connection is surprisingly simple. It usually happens over stdio (standard input/output) for local tools or HTTP/SSE for remote servers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Client (e.g., Claude) starts your MCP Server script.&lt;/li&gt;
&lt;li&gt;The Server sends a list of available tools (e.g., get_user_data, search_logs).&lt;/li&gt;
&lt;li&gt;The AI decides when to call a tool based on your conversation.&lt;/li&gt;
&lt;li&gt;The Server executes the logic and sends the result back.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📂 Public Example Repository
&lt;/h2&gt;

&lt;p&gt;Want to see code? The best way to learn is by looking at the official reference implementations. The repository below contains a collection of ready-to-use MCP servers for things like Google Drive, PostgreSQL, Slack, and GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔗 Repository
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/modelcontextprotocol/servers" rel="noopener noreferrer"&gt;modelcontextprotocol/servers&lt;/a&gt;&lt;br&gt;
Why check this repo?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple Examples: See how to structure servers for different use cases (File systems vs. APIs).&lt;/li&gt;
&lt;li&gt;TypeScript &amp;amp; Python: Examples in the most popular languages.&lt;/li&gt;
&lt;li&gt;Plug &amp;amp; Play: You can clone this and connect it to your Claude Desktop immediately to test it out.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🎯 Next Steps
&lt;/h2&gt;

&lt;p&gt;If you want to empower our AI workflows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone the repo linked above.&lt;/li&gt;
&lt;li&gt;Pick one server (e.g., the sqlite or filesystem server).&lt;/li&gt;
&lt;li&gt;Connect it to your Claude Desktop config file.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🏁 Conclusion
&lt;/h2&gt;

&lt;p&gt;The Model Context Protocol isn't just a new tool; it's a standard that ends the era of siloed AI. By adopting MCP, we move from building fragile, one-off integrations to creating a robust ecosystem where our data and AI agents communicate freely.&lt;/p&gt;

&lt;p&gt;Instead of manually feeding context to an AI every time we start a task, MCP creates a live, two-way bridge. Whether we are debugging code in VSCode or analyzing business data in Claude, MCP puts the knowledge where it belongs: at the AI's fingertips.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>📝The Age of Observability: Navigating Chaos in Distributed Systems</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Sat, 22 Nov 2025 15:13:13 +0000</pubDate>
      <link>https://forem.com/brunoenr/the-age-of-observability-navigating-chaos-in-distributed-systems-3a4f</link>
      <guid>https://forem.com/brunoenr/the-age-of-observability-navigating-chaos-in-distributed-systems-3a4f</guid>
      <description>&lt;p&gt;In the era of monoliths, system failure was binary: the server was either up or down. Troubleshooting was linear—you checked the CPU, memory, and disk space. However, the shift to microservices, serverless architectures, and Kubernetes has introduced a level of complexity where linear debugging no longer works.&lt;/p&gt;

&lt;p&gt;In distributed systems, failure is rarely a crash; it is a performance degradation. A user complains that "checkout is slow," but all your dashboards show green lights. This is the "unknown unknown." To solve this, we must move beyond simple monitoring and embrace Observability.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍 Monitoring vs. Observability: What’s the Difference?
&lt;/h2&gt;

&lt;p&gt;Many engineers use these terms interchangeably, but they represent fundamentally different approaches to system visibility.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Monitoring tells you when something is wrong based on pre-defined thresholds. It answers questions you knew to ask in advance (e.g., "Is CPU &amp;gt; 90%?"). It is reactive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Observability allows you to ask new questions about your system to understand why something is wrong. It relies on exploring the data to find patterns you didn't know existed. It is exploratory.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;"Monitoring tells you the system is failing. Observability lets you understand why."&lt;/p&gt;

&lt;h2&gt;
  
  
  🏛️ The Three Pillars of Observability
&lt;/h2&gt;

&lt;p&gt;To build an observable system, we need to collect three specific types of telemetry data.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📜 Logs (The Event Record) Logs are immutable, timestamped records of discrete events.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Problem: Traditional text logs are hard to search.&lt;/p&gt;

&lt;p&gt;The Solution: Structured Logging. Instead of logging "User login failed", log {"event": "login_failed", "user_id": "123", "error": "timeout"}. This allows log aggregation tools to filter and index data instantly.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📊 Metrics (The Health Check) Metrics are numerical data measured over time. They are cheap to store and fast to query.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use Case: Dashboards and Alerts.&lt;/p&gt;

&lt;p&gt;Limitation: Metrics suffer from "low cardinality." They are great for seeing trends (e.g., total error rate) but terrible for finding specific needles in the haystack (e.g., which specific user ID caused the error).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔗 Traces (The Journey) Distributed Tracing is the most critical tool for microservices. It tracks the lifecycle of a request as it propagates across service boundaries.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Trace ID: A unique identifier attached to the request at the entry point.&lt;/p&gt;

&lt;p&gt;Span: Represents a single operation within that trace (e.g., a database query or an external API call).&lt;/p&gt;

&lt;p&gt;Benefit: Tracing visualizes latency, proving instantly that the delay is not in your API, but in the legacy SQL database you queried.&lt;/p&gt;

&lt;h2&gt;
  
  
  🚦 The Four Golden Signals
&lt;/h2&gt;

&lt;p&gt;According to the Google SRE (Site Reliability Engineering) handbook, if you can only measure four things in your user-facing system, measure these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Latency: The time it takes to service a request. It is crucial to distinguish between the latency of successful requests and the latency of failed requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Traffic: A measure of how much demand is being placed on your system (e.g., HTTP requests per second).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Errors: The rate of requests that fail (e.g., HTTP 500s) or partially fail.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Saturation: How "full" your service is. This measures your most constrained resource (e.g., memory or I/O).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ⚙️ Instrumentation Strategies: How to Start?
&lt;/h2&gt;

&lt;p&gt;You cannot buy observability; you must build it into your code. This process is called Instrumentation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automatic Instrumentation: Many agents (like Datadog or New Relic) can attach to your running process and extract data without code changes. This is the easiest way to start.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manual Instrumentation: This involves writing code to capture business-specific data (e.g., tracking how many times a specific "Add to Cart" button was clicked).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;OpenTelemetry (OTel): The modern industry standard. OTel provides a vendor-neutral way to instrument your application. You write your instrumentation once, and you can export that data to Azure, AWS, Prometheus, or Jaeger without changing a single line of code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📦GitHub Repository
&lt;/h2&gt;

&lt;p&gt;A working implementation is available here: &lt;a href="https://github.com/Brunoenr02/Observability" rel="noopener noreferrer"&gt;View the full source code and setup guide on my GitHub&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🚀 Conclusion
&lt;/h2&gt;

&lt;p&gt;Observability is a property of your system, not a feature of your software tool. By implementing structured logs, meaningful metrics, and distributed tracing, you turn the "black box" of production into a "glass box." This culture of visibility allows teams to deploy faster, debug efficiently, and sleep better at night.&lt;/p&gt;

</description>
      <category>distributedsystems</category>
      <category>monitoring</category>
      <category>performance</category>
      <category>devops</category>
    </item>
    <item>
      <title>Unlocking Scalability: A Deep Dive into the Model-View-Controller (MVC) Pattern</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Tue, 28 Oct 2025 01:35:15 +0000</pubDate>
      <link>https://forem.com/brunoenr/unlocking-scalability-a-deep-dive-into-the-model-view-controller-mvc-pattern-342h</link>
      <guid>https://forem.com/brunoenr/unlocking-scalability-a-deep-dive-into-the-model-view-controller-mvc-pattern-342h</guid>
      <description>&lt;p&gt;Here is an article about the Model-View-Controller pattern, complete with a real-world example in Python using the Flask framework.&lt;/p&gt;

&lt;p&gt;Unlocking Scalability: A Deep Dive into the Model-View-Controller (MVC) Pattern&lt;br&gt;
In the world of software engineering, especially within enterprise-level applications, complexity is the main enemy. As applications grow, adding new features, fixing bugs, and managing the codebase can become a nightmare. To combat this, architects rely on proven design patterns. These patterns are reusable solutions to common problems.&lt;/p&gt;

&lt;p&gt;One of the most foundational patterns, featured prominently in catalogs like Martin Fowler's "Patterns of Enterprise Application Architecture," is the Model-View-Controller (MVC). While it originated in Smalltalk-80 for desktop applications, its principles are fundamental to how most modern web applications are built today.&lt;/p&gt;

&lt;p&gt;This article explores the MVC pattern: what it is, why it's crucial for enterprise applications, and how to implement it with a practical, real-world example in Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍What is the Model-View-Controller (MVC) Pattern?
&lt;/h2&gt;

&lt;p&gt;The MVC pattern is an architectural pattern that separates an application's logic into three distinct, interconnected components. The primary goal is Separation of Concerns. By keeping these parts separate, the application becomes easier to test, maintain, and scale.&lt;/p&gt;

&lt;p&gt;Here’s a breakdown of the three components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Model: This is the brain of the application. It represents the data, business logic, and rules.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;It manages the application's state (e.g., data from a database).&lt;/li&gt;
&lt;li&gt;It contains the business logic (e.g., "a user cannot withdraw more money than they have").&lt;/li&gt;
&lt;li&gt;It knows nothing about the View or the Controller. It is a standalone component.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;The View: This is the face of the application. It's the User Interface (UI) that the end-user interacts with.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;It displays the data it receives from the Model.&lt;/li&gt;
&lt;li&gt;It sends user actions (like button clicks or form submissions) to the Controller.&lt;/li&gt;
&lt;li&gt;It should be "dumb"—it contains no business logic. Its only job is presentation.&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;The Controller: This is the traffic cop or intermediary. It glues the Model and the View together.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;It receives input from the View (e.g., an HTTP request from a user).&lt;/li&gt;
&lt;li&gt;It processes that input, interacts with the Model (e.g., "Hey Model, add this new user to the database"), and gets a response.&lt;/li&gt;
&lt;li&gt;It then decides which View to show the user and passes it the necessary data from the Model.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🔍Why MVC is Essential for Enterprise Applications
&lt;/h2&gt;

&lt;p&gt;The separation provided by MVC isn't just an academic exercise; it provides tangible business value:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Testability: Because the Model (business logic) is separate from the UI, you can write automated tests for your core logic without ever needing to render a webpage or simulate a click. This makes testing more robust and faster.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Maintainability: Need to change a button color or redesign a page? You only touch the View. The core business logic in the Model remains untouched and safe.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Flexibility: The same Model can serve multiple Views. You can have a web interface (View 1) and a mobile app (View 2) that both talk to the same Controller and Model. This "write once, use many" approach is incredibly efficient.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  💻Real-World Example: A Python To-Do List with Flask
&lt;/h2&gt;

&lt;p&gt;Let's build a simple "To-Do List" web application. We'll use Python and the micro-framework Flask. While some frameworks like Django call their pattern MVT (Model-View-Template), the principle is identical. We will structure our code to clearly separate the three concerns.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project Structure
Create a folder for your project. Inside, it should look like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvc-todo-app/
├── app.py           # The Controller
├── model.py         # The Model
└── templates/
    └── index.html   # The View
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The Model (model.py)
This file contains our data and business logic. For simplicity, we won't use a real database; we'll use a simple list in memory. This file does not import Flask. It's pure Python.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# model.py

# We'll use a simple list to act as our "database"
tasks = []
task_id_counter = 1

class TaskModel:
    """
    The Model component. It handles the data and business logic
    for our tasks. It knows nothing about HTTP or the web.
    """

    def get_all_tasks(self):
        """Retrieves all tasks."""
        return tasks

    def add_task(self, description):
        """Adds a new task to our list."""
        global task_id_counter
        if not description:
            # Business logic: Don't allow empty tasks
            return None

        new_task = {
            'id': task_id_counter,
            'description': description,
            'completed': False
        }
        tasks.append(new_task)
        task_id_counter += 1
        return new_task

    def complete_task(self, task_id):
        """Marks a specific task as completed."""
        for task in tasks:
            if task['id'] == task_id:
                task['completed'] = True
                return task
        return None # Task not found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The View (templates/index.html)
This is our UI. It's an HTML file that uses the Jinja2 templating engine (which comes with Flask).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;MVC To-Do List&amp;lt;/title&amp;gt;
    &amp;lt;style&amp;gt;
        body { font-family: sans-serif; margin: 2em; }
        .task-list { list-style: none; padding: 0; }
        .task { margin-bottom: 8px; }
        .completed { text-decoration: line-through; color: #888; }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;My To-Do List&amp;lt;/h1&amp;gt;

    &amp;lt;form action="/add" method="POST"&amp;gt;
        &amp;lt;label for="task"&amp;gt;New Task:&amp;lt;/label&amp;gt;
        &amp;lt;input type="text" id="task" name="description"&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Add Task&amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;

    &amp;lt;hr&amp;gt;

    &amp;lt;h2&amp;gt;Current Tasks&amp;lt;/h2&amp;gt;
    &amp;lt;ul class="task-list"&amp;gt;
        {% for task in tasks %}
            &amp;lt;li class="task {% if task.completed %}completed{% endif %}"&amp;gt;
                {{ task.description }}

                {% if not task.completed %}
                    ( &amp;lt;a href="/complete/{{ task.id }}"&amp;gt;Complete&amp;lt;/a&amp;gt; )
                {% endif %}
            &amp;lt;/li&amp;gt;
        {% else %}
            &amp;lt;li&amp;gt;No tasks yet!&amp;lt;/li&amp;gt;
        {% endfor %}
    &amp;lt;/ul&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The Controller (app.py)
This is the "glue." It imports Flask and our TaskModel. It defines the URL routes that listen for user input from the View, processes that input using the Model, and then renders the View with the new data.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from flask import Flask, render_template, request, redirect, url_for
from model import TaskModel # Import the Model

app = Flask(__name__)
model = TaskModel()

@app.route('/')
def index():
    """
    Handles the main route.
    1. Gets all tasks from the Model.
    2. Renders the View, passing the tasks to it.
    """
    tasks = model.get_all_tasks()
    return render_template('index.html', tasks=tasks)

@app.route('/add', methods=['POST'])
def add_task():
    """
    Handles the 'Add Task' form submission.
    1. Gets form data from the user request (View).
    2. Tells the Model to add the new task.
    3. Redirects the user back to the main page.
    """
    description = request.form.get('description')
    model.add_task(description)
    return redirect(url_for('index'))

@app.route('/complete/&amp;lt;int:task_id&amp;gt;')
def complete_task(task_id):
    """
    Handles the 'Complete' link click.
    1. Gets the task_id from the URL (View).
    2. Tells the Model to mark the task as complete.
    3. Redirects the user back to the main page.
    """
    model.complete_task(task_id)
    return redirect(url_for('index'))

if __name__ == '__main__':
    app.run(debug=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📦GitHub Repository
&lt;/h2&gt;

&lt;p&gt;A working implementation is available here: &lt;a href="https://github.com/Brunoenr02/Model-View-Controller-MVC-Pattern" rel="noopener noreferrer"&gt;Model View Controller&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅Conclusion
&lt;/h2&gt;

&lt;p&gt;The Model-View-Controller pattern is not just a theory; it's a practical, powerful, and time-tested strategy for building software that lasts. By separating the Model (logic), the View (UI), and the Controller (input handler), you create an application that is a pleasure to test, maintain, and expand.&lt;/p&gt;

&lt;p&gt;While modern frameworks have evolved this idea into patterns like MVVM (Model-View-ViewModel) or MVT (Model-View-Template), they all share the same DNA. Understanding MVC is the first and most critical step toward building clean, scalable, and professional enterprise-grade applications.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>designpatterns</category>
      <category>python</category>
    </item>
    <item>
      <title>📊Beyond the Standard: Exploring Modern Python Visualization Tools</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Sun, 14 Sep 2025 03:19:57 +0000</pubDate>
      <link>https://forem.com/brunoenr/beyond-the-standard-exploring-modern-python-visualization-tools-3epn</link>
      <guid>https://forem.com/brunoenr/beyond-the-standard-exploring-modern-python-visualization-tools-3epn</guid>
      <description>&lt;p&gt;In the world of data science, moving from a static Jupyter notebook to a dynamic, interactive web application is a game-changer. It allows stakeholders to explore data, test hypotheses, and gain insights on their own. While tools like Tableau or Power BI have their place, a code-first approach using Python offers unparalleled flexibility and power.&lt;/p&gt;

&lt;p&gt;This article dives into three powerful Python libraries for building dashboards and reports: Streamlit, Dash, and Bokeh. We'll explore the philosophy behind each, build a simple interactive dashboard with all three, and walk through deploying our app to the cloud, complete with a GitHub repository and CI/CD automation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 The Contenders&lt;/strong&gt;&lt;br&gt;
Let's meet our three visualization frameworks. Each has a unique approach to turning Python scripts into interactive web apps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Streamlit ✨&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The Pitch: The fastest way to build and share data apps.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Streamlit is the go-to for data scientists who want to create beautiful, functional apps with minimal effort and without thinking about traditional web development. Its core philosophy is simplicity. You write a Python script as you normally would, and Streamlit intelligently re-runs your code from top to bottom whenever a user interacts with a widget.&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅Aidiculously easy to learn.&lt;/li&gt;
&lt;li&gt;✅Minimal boilerplate code.&lt;/li&gt;
&lt;li&gt;✅Automatic updates on widget interaction.&lt;/li&gt;
&lt;li&gt;✅A rich ecosystem of custom components.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌The "rerun everything" model can be inefficient for very complex or long-running apps.&lt;/li&gt;
&lt;li&gt;❌Less control over the fine-grained layout and styling compared to others.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Plotly Dash 📊&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The Pitch: Build analytical web apps for Python. No JavaScript required.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dash, created by the team behind the Plotly charting library, is a powerful framework for building production-ready, enterprise-grade applications. It provides a more structured "blank canvas" where you define the layout using Python classes that mimic HTML and then connect interactive components using explicit "callbacks."&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅Highly customizable and flexible layouts.&lt;/li&gt;
&lt;li&gt;✅Scalable for complex, multi-page applications.&lt;/li&gt;
&lt;li&gt;✅Excellent for apps requiring precise state management.&lt;/li&gt;
&lt;li&gt;✅Part of the robust Plotly ecosystem.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌Steeper learning curve with more boilerplate code.&lt;/li&gt;
&lt;li&gt;❌Requires a deeper understanding of concepts like layouts and callbacks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Bokeh 🎨&lt;/strong&gt;&lt;br&gt;
&lt;em&gt;The Pitch: Interactive visualizations for modern web browsers.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Bokeh is, at its core, a visualization library, but it comes with a powerful server component that allows you to build full-fledged interactive applications. It excels at handling large datasets and streaming data efficiently. Its strength lies in the granular control it gives you over every plot element and its powerful data linking and selection tools.&lt;/p&gt;

&lt;p&gt;Pros:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅Excellent for high-performance interactivity on large datasets.&lt;/li&gt;
&lt;li&gt;✅Provides a high level of control over plot design and interactions.&lt;/li&gt;
&lt;li&gt;✅Can be used as a standalone library or with its server for full apps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;❌Can be more verbose for creating full dashboard layouts compared to Streamlit.&lt;/li&gt;
&lt;li&gt;❌The API can feel less "Pythonic" initially than Streamlit's.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🐧 The Demo Project: Palmer Penguins Explorer&lt;/strong&gt;&lt;br&gt;
To compare these tools, we'll build the same simple app in all three: an interactive scatter plot explorer for the famous Palmer Penguins dataset. Users will be able to select the species to display and choose the variables for the X and Y axes.&lt;/p&gt;

&lt;p&gt;First, let's install our libraries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install streamlit pandas plotly-express dash bokeh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;1. Streamlit Example&lt;/strong&gt;&lt;br&gt;
Notice how clean and readable this is. We use st.sidebar to place our widgets and the main area for the plot. The code reads like a simple script.&lt;/p&gt;

&lt;p&gt;streamlit_app/app.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import streamlit as st
import pandas as pd
import plotly.express as px

# Load the dataset
@st.cache_data # Cache the data to improve performance
def load_data():
    df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv')
    df.dropna(inplace=True)
    return df

df = load_data()

# --- Page Configuration ---
st.set_page_config(
    page_title="🐧 Palmer Penguins Explorer",
    page_icon="🧊",
    layout="centered"
)

st.title("🐧 Palmer Penguins Explorer")
st.markdown("Explore the Palmer Penguins dataset using **Streamlit**.")

# --- Sidebar for User Inputs ---
st.sidebar.header("📊 Chart Controls")

# Species selector
species_list = ['All'] + sorted(df['species'].unique().tolist())
selected_species = st.sidebar.selectbox("Select Species", species_list)

# Axis selectors
numeric_columns = df.select_dtypes(include=['float64', 'int64']).columns.tolist()
x_axis = st.sidebar.selectbox("Select X-axis", numeric_columns, index=numeric_columns.index('bill_length_mm'))
y_axis = st.sidebar.selectbox("Select Y-axis", numeric_columns, index=numeric_columns.index('bill_depth_mm'))

# --- Data Filtering ---
if selected_species != 'All':
    filtered_df = df[df['species'] == selected_species]
else:
    filtered_df = df

# --- Display Chart ---
st.subheader(f"Scatter Plot: {x_axis} vs. {y_axis}")

if not filtered_df.empty:
    fig = px.scatter(
        filtered_df,
        x=x_axis,
        y=y_axis,
        color='species',
        hover_name='species',
        title=f'Relationship between {x_axis} and {y_axis}'
    )
    st.plotly_chart(fig, use_container_width=True)
else:
    st.warning("No data available for the selected species.")

st.markdown("---")
st.write("Data Source:")
st.dataframe(filtered_df.head())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Dash Example&lt;/strong&gt;&lt;br&gt;
Dash is more structured. We define a static layout and then create a @app.callback function that listens for changes to the inputs (species-dropdown, x-axis-dropdown, y-axis-dropdown) and updates the output (penguin-scatter-plot).&lt;/p&gt;

&lt;p&gt;dash_app/app.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import dash
from dash import dcc, html, Input, Output
import pandas as pd
import plotly.express as px

# Load the dataset
df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv')
df.dropna(inplace=True)

# --- App Initialization ---
app = dash.Dash(__name__)
server = app.server # Expose server for deployment

numeric_columns = df.select_dtypes(include=['float64', 'int64']).columns.tolist()
species_list = [{'label': 'All', 'value': 'All'}] + [{'label': s, 'value': s} for s in sorted(df['species'].unique())]

# --- App Layout ---
app.layout = html.Div(style={'fontFamily': 'sans-serif'}, children=[
    html.H1("🐧 Palmer Penguins Explorer (Dash)", style={'textAlign': 'center'}),
    html.P("Explore the Palmer Penguins dataset using Plotly Dash.", style={'textAlign': 'center'}),

    html.Div(style={'display': 'flex', 'padding': '20px'}, children=[
        # Controls Div
        html.Div(style={'width': '25%', 'paddingRight': '20px'}, children=[
            html.H3("📊 Chart Controls"),
            html.Label("Select Species"),
            dcc.Dropdown(id='species-dropdown', options=species_list, value='All'),
            html.Br(),
            html.Label("Select X-axis"),
            dcc.Dropdown(id='x-axis-dropdown', options=[{'label': i, 'value': i} for i in numeric_columns], value='bill_length_mm'),
            html.Br(),
            html.Label("Select Y-axis"),
            dcc.Dropdown(id='y-axis-dropdown', options=[{'label': i, 'value': i} for i in numeric_columns], value='bill_depth_mm'),
        ]),

        # Graph Div
        html.Div(style={'width': '75%'}, children=[
            dcc.Graph(id='penguin-scatter-plot')
        ])
    ])
])

# --- Callback for Interactivity ---
@app.callback(
    Output('penguin-scatter-plot', 'figure'),
    [Input('species-dropdown', 'value'),
     Input('x-axis-dropdown', 'value'),
     Input('y-axis-dropdown', 'value')]
)
def update_graph(selected_species, x_axis, y_axis):
    if selected_species == 'All' or selected_species is None:
        filtered_df = df
    else:
        filtered_df = df[df['species'] == selected_species]

    fig = px.scatter(
        filtered_df,
        x=x_axis,
        y=y_axis,
        color='species',
        hover_name='species',
        title=f'Relationship between {x_axis} and {y_axis}'
    )
    fig.update_layout(transition_duration=500)
    return fig

# --- Run the App ---
if __name__ == '__main__':
    app.run_server(debug=True)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Bokeh Example&lt;/strong&gt;&lt;br&gt;
Bokeh requires us to think more about data sources and how glyphs (like circles) are updated. Here, we create a ColumnDataSource and a callback function that modifies the data within this source when a widget changes.&lt;/p&gt;

&lt;p&gt;bokeh_app/app.py&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource, Select
from bokeh.layouts import column, row
from bokeh.palettes import Category10_3

# Load the dataset
df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv')
df.dropna(inplace=True)

# Map species to colors
species_unique = sorted(df['species'].unique())
color_map = {species: Category10_3[i] for i, species in enumerate(species_unique)}
df['color'] = df['species'].map(color_map)

# Create a ColumnDataSource
source = ColumnDataSource(data=df)

# --- Create Widgets ---
numeric_columns = df.select_dtypes(include=['float64', 'int64']).columns.tolist()
species_list = ['All'] + species_unique

x_axis_select = Select(title="Select X-axis", value="bill_length_mm", options=numeric_columns)
y_axis_select = Select(title="Select Y-axis", value="bill_depth_mm", options=numeric_columns)
species_select = Select(title="Select Species", value="All", options=species_list)

# --- Create the Plot ---
p = figure(height=500, width=700, title="Penguin Scatter Plot", tooltips=[("Species", "@species"), ("X", "@x"), ("Y", "@y")])
p.circle(x="x", y="y", source=source, size=10, color="color", legend_field="species")
p.xaxis.axis_label = x_axis_select.value
p.yaxis.axis_label = y_axis_select.value

# --- Define the Callback ---
def update_plot(attr, old, new):
    # Filter data based on species selection
    if species_select.value == 'All':
        filtered_df = df
    else:
        filtered_df = df[df.species == species_select.value]

    # Update source data
    source.data = {
        'x': filtered_df[x_axis_select.value],
        'y': filtered_df[y_axis_select.value],
        'species': filtered_df['species'],
        'color': filtered_df['color']
    }

    # Update axis labels
    p.xaxis.axis_label = x_axis_select.value
    p.yaxis.axis_label = y_axis_select.value

# Attach the callback to the 'value' property of each widget
for widget in [x_axis_select, y_axis_select, species_select]:
    widget.on_change('value', update_plot)

# --- Arrange Layout ---
controls = column(species_select, x_axis_select, y_axis_select, width=200)
layout = row(controls, p)

# Initialize the plot data
update_plot(None, None, None) 

curdoc().add_root(layout)
curdoc().title = "🐧 Palmer Penguins Explorer (Bokeh)"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📦GitHub Repository&lt;/strong&gt;&lt;br&gt;
A working implementation is available here:&lt;br&gt;
🔗&lt;a href="https://github.com/Brunoenr02/Other-Visualization-Tools" rel="noopener noreferrer"&gt;Other Visualization Tools&lt;/a&gt;&lt;br&gt;
🚀&lt;a href="https://other-visualization-tools.streamlit.app/" rel="noopener noreferrer"&gt;Deploy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅Conclusion: Which Tool Should You Use?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Choose Streamlit if: You are a data scientist who needs to build a beautiful, interactive tool quickly. You value simplicity and speed over granular control. Perfect for prototypes, internal tools, and ML model demos.&lt;/li&gt;
&lt;li&gt;Choose Dash if: You are building a complex, production-ready application that requires a specific layout, multi-page functionality, and robust state management. You are comfortable with more boilerplate and a callback-driven architecture.&lt;/li&gt;
&lt;li&gt;Choose Bokeh if: Your primary need is highly interactive, high-performance plotting, especially with large or streaming datasets. You want fine-grained control over your visualizations and are comfortable building the UI around them.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>devops</category>
      <category>datascience</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>📝Enterprise Design Patterns: Repository Pattern in Enterprise Applications</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Sat, 06 Sep 2025 04:03:09 +0000</pubDate>
      <link>https://forem.com/brunoenr/enterprise-design-patterns-repository-pattern-in-enterprise-applications-3271</link>
      <guid>https://forem.com/brunoenr/enterprise-design-patterns-repository-pattern-in-enterprise-applications-3271</guid>
      <description>&lt;p&gt;Enterprise software development often involves handling complex domains, large datasets, and ever-evolving requirements. To manage this complexity, enterprise design patterns—as cataloged by Martin Fowler in his book Patterns of Enterprise Application Architecture—provide reusable solutions that improve code organization, scalability, and maintainability.&lt;/p&gt;

&lt;p&gt;One of the most widely used patterns is the Repository Pattern.&lt;/p&gt;

&lt;p&gt;🔍&lt;strong&gt;What is the Repository Pattern?&lt;/strong&gt;&lt;br&gt;
The Repository Pattern acts as a mediator between the domain (business logic) and the data mapping layers (databases, APIs, etc.). Instead of having application logic directly query the database, the repository provides a clean API for retrieving and persisting domain objects.&lt;/p&gt;

&lt;p&gt;This brings several benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decouples business logic from persistence details.&lt;/li&gt;
&lt;li&gt;Provides a more object-oriented view of data.&lt;/li&gt;
&lt;li&gt;Centralizes data access logic.&lt;/li&gt;
&lt;li&gt;Makes unit testing easier by mocking repositories.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔍&lt;strong&gt;Context about Enterprise Application Architecture&lt;/strong&gt;&lt;br&gt;
The Repository Pattern is just one of many patterns described by Martin Fowler in his influential book Patterns of Enterprise Application Architecture (EAA). This catalog provides proven design solutions for recurring problems in large-scale business applications, where complexity, scalability, and maintainability are constant challenges.&lt;/p&gt;

&lt;p&gt;Some of the most important categories in the EAA catalog include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain Logic Patterns – How to structure the core business rules of an application. Examples: Transaction Script, Domain Model, Table Module.&lt;/li&gt;
&lt;li&gt;Data Source Architectural Patterns – How to handle the persistence layer and communication with databases. Examples: Data Mapper, Active Record, Repository.&lt;/li&gt;
&lt;li&gt;Object-Relational Behavioral Patterns – How objects interact with relational databases. Examples: Unit of Work, Identity Map, Lazy Load.&lt;/li&gt;
&lt;li&gt;Web Presentation Patterns – How to structure user interfaces in enterprise web systems. Examples: Model View Controller (MVC), Page Controller, Front Controller.&lt;/li&gt;
&lt;li&gt;Distribution Patterns – How to deal with distributed systems and remote calls. Examples: Remote Facade, Data Transfer Object (DTO).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By combining these patterns, enterprise developers can design systems that are easier to understand, test, and evolve. The Repository Pattern fits into the Data Source Architectural Patterns category, since its main goal is to separate domain logic from data persistence logic.&lt;/p&gt;

&lt;p&gt;💻&lt;strong&gt;Real-World Example: Repository Pattern in Python&lt;/strong&gt;&lt;br&gt;
Imagine a simple enterprise app where we manage customers.&lt;br&gt;
Step 1: Define the Domain Model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# domain/customer.py
class Customer:
    def __init__(self, customer_id: int, name: str, email: str):
        self.customer_id = customer_id
        self.name = name
        self.email = email

    def __repr__(self):
        return f"Customer(id={self.customer_id}, name='{self.name}', email='{self.email}')"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 2: Define the Repository Interface&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# repository/customer_repository.py
from abc import ABC, abstractmethod
from typing import List, Optional
from domain.customer import Customer

class CustomerRepository(ABC):
    @abstractmethod
    def add(self, customer: Customer) -&amp;gt; None:
        pass

    @abstractmethod
    def get_by_id(self, customer_id: int) -&amp;gt; Optional[Customer]:
        pass

    @abstractmethod
    def list_all(self) -&amp;gt; List[Customer]:
        pass
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 3: Implement a Concrete Repository (e.g., In-Memory)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# repository/in_memory_customer_repository.py
from typing import List, Optional
from domain.customer import Customer
from repository.customer_repository import CustomerRepository

class InMemoryCustomerRepository(CustomerRepository):
    def __init__(self):
        self._customers = {}

    def add(self, customer: Customer) -&amp;gt; None:
        self._customers[customer.customer_id] = customer

    def get_by_id(self, customer_id: int) -&amp;gt; Optional[Customer]:
        return self._customers.get(customer_id)

    def list_all(self) -&amp;gt; List[Customer]:
        return list(self._customers.values())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Step 4: Use the Repository in Application Logic&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# app.py
from domain.customer import Customer
from repository.in_memory_customer_repository import InMemoryCustomerRepository

if __name__ == "__main__":
    repo = InMemoryCustomerRepository()

    # Add customers
    repo.add(Customer(1, "Alice", "alice@example.com"))
    repo.add(Customer(2, "Bob", "bob@example.com"))

    # Retrieve one customer
    print(repo.get_by_id(1))

    # List all customers
    print(repo.list_all())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When running python app.py, the output will be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer(id=1, name='Alice', email='alice@example.com')
[Customer(id=1, name='Alice', email='alice@example.com'), Customer(id=2, name='Bob', email='bob@example.com')]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;📦&lt;strong&gt;GitHub Repository&lt;/strong&gt;&lt;br&gt;
A working implementation of the Repository Pattern (including tests and CI/CD) is available here:&lt;br&gt;
🔗&lt;a href="https://github.com/Brunoenr02/Enterprise_Design_Patterns" rel="noopener noreferrer"&gt;Enterprise_Design_Patterns&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain models (domain/) – business entities such as Customer.&lt;/li&gt;
&lt;li&gt;Repositories (repository/) – repository interfaces and implementations.&lt;/li&gt;
&lt;li&gt;Application entry point (app.py) – demonstrates how to use the repository.&lt;/li&gt;
&lt;li&gt;Unit tests (tests/) – test cases validating repository behavior.&lt;/li&gt;
&lt;li&gt;GitHub Actions workflow (.github/workflows/python-ci.yml) – runs continuous testing on every push or pull request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br&gt;
The Repository Pattern from Martin Fowler’s Patterns of Enterprise Application Architecture provides a clean way to abstract persistence logic in enterprise applications. By separating the domain model from the data access layer, applications become easier to maintain, test, and scale.&lt;br&gt;
With GitHub integration and CI automation, the repository pattern becomes even more powerful in modern software engineering practices.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Software Design Principles (with Real-World Python Example)</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Sat, 06 Sep 2025 03:19:22 +0000</pubDate>
      <link>https://forem.com/brunoenr/software-design-principles-with-real-world-python-example-4c1c</link>
      <guid>https://forem.com/brunoenr/software-design-principles-with-real-world-python-example-4c1c</guid>
      <description>&lt;h2&gt;
  
  
  &amp;gt; &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Software design is not only about writing code that works — it’s about creating systems that are maintainable, scalable, and easy to understand. As applications grow, poorly structured code quickly becomes difficult to modify or extend, leading to bugs and unnecessary complexity.&lt;/p&gt;

&lt;p&gt;To prevent this, developers rely on design principles: guidelines that help us write cleaner, more adaptable code. Among these, the most widely known are the SOLID principles.&lt;/p&gt;

&lt;h2&gt;
  
  
  &amp;gt; &lt;strong&gt;The SOLID Principles&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Single Responsibility Principle (SRP)&lt;br&gt;
A class should have only one reason to change. This avoids classes that are overloaded with multiple responsibilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open/Closed Principle (OCP)&lt;br&gt;
Software entities should be open for extension but closed for modification. We should be able to add new features without rewriting existing code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Liskov Substitution Principle (LSP)&lt;br&gt;
Subtypes must be substitutable for their base types without altering the correctness of the program.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interface Segregation Principle (ISP)&lt;br&gt;
Clients should not be forced to depend on methods they don’t use. Interfaces should be small and focused.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency Inversion Principle (DIP)&lt;br&gt;
High-level modules should not depend on low-level modules. Both should depend on abstractions.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &amp;gt; &lt;strong&gt;Real-World Example: A Notification System&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Let’s imagine an application that sends notifications via different channels: email, SMS, and push.&lt;/p&gt;

&lt;p&gt;❌ Poor Design (Violates SRP and OCP)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class NotificationService:
    def send_notification(self, message: str, channel: str):
        if channel == "email":
            print(f"Sending EMAIL: {message}")
        elif channel == "sms":
            print(f"Sending SMS: {message}")
        elif channel == "push":
            print(f"Sending PUSH: {message}")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SRP Violation: One class handles multiple notification types.&lt;/li&gt;
&lt;li&gt;OCP Violation: Adding a new channel requires editing this class.&lt;/li&gt;
&lt;li&gt;Hard to Test: Logic for different responsibilities is mixed together.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;✅ Improved Design (Applies SOLID in Python)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from abc import ABC, abstractmethod

# Abstraction (DIP, OCP)
class Notifier(ABC):
    @abstractmethod
    def send(self, message: str) -&amp;gt; None:
        pass

# Concrete implementations (SRP: one responsibility each)
class EmailNotifier(Notifier):
    def send(self, message: str) -&amp;gt; None:
        print(f"Sending EMAIL: {message}")

class SMSNotifier(Notifier):
    def send(self, message: str) -&amp;gt; None:
        print(f"Sending SMS: {message}")

class PushNotifier(Notifier):
    def send(self, message: str) -&amp;gt; None:
        print(f"Sending PUSH: {message}")

# Service that depends on abstraction (DIP)
class NotificationService:
    def __init__(self, notifier: Notifier):
        self.notifier = notifier

    def notify(self, message: str) -&amp;gt; None:
        self.notifier.send(message)

# Example usage
if __name__ == "__main__":
    email_service = NotificationService(EmailNotifier())
    sms_service = NotificationService(SMSNotifier())
    push_service = NotificationService(PushNotifier())

    email_service.notify("Welcome to our platform!")
    sms_service.notify("Your OTP is 123456")
    push_service.notify("You have a new message")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why This Design is Better&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SRP: Each class has a single job (email, SMS, or push).&lt;/li&gt;
&lt;li&gt;OCP: Adding a new channel (e.g., SlackNotifier) requires no modification to existing code.&lt;/li&gt;
&lt;li&gt;LSP: Any Notifier subclass can replace another without breaking the program.&lt;/li&gt;
&lt;li&gt;DIP: NotificationService depends on the abstract Notifier, not concrete implementations.&lt;/li&gt;
&lt;li&gt;Testability: Each notifier can be tested independently.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &amp;gt; &lt;strong&gt;Additional Design Concepts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;While SOLID is a cornerstone, there are other important design principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DRY (Don’t Repeat Yourself): Avoid code duplication by extracting reusable components.&lt;/li&gt;
&lt;li&gt;KISS (Keep It Simple, Stupid): Simpler solutions are easier to maintain and less error-prone.&lt;/li&gt;
&lt;li&gt;YAGNI (You Aren’t Gonna Need It): Don’t add functionality until it’s actually required.&lt;/li&gt;
&lt;li&gt;Composition Over Inheritance: Favor combining objects over deep inheritance hierarchies for flexibility.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Together, these principles help prevent code bloat, reduce bugs, and improve collaboration in large teams.&lt;/p&gt;

&lt;h2&gt;
  
  
  &amp;gt; &lt;strong&gt;GitHub Repository with Automation&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A working implementation of this notification system (including tests and CI/CD) is available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Brunoenr02/software_design_principles_python" rel="noopener noreferrer"&gt;Software_design_principles_python&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The repository contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Source code (src/)&lt;/li&gt;
&lt;li&gt;Unit tests (tests/)&lt;/li&gt;
&lt;li&gt;A GitHub Actions workflow (.github/workflows/python-app.yml) for continuous testing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &amp;gt; &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Design principles are more than abstract theory: they shape how maintainable and extendable our systems are. By applying principles like SOLID, DRY, and KISS to something as simple as a notification system, we get code that is flexible, testable, and future-proof.&lt;/p&gt;

&lt;p&gt;When applied consistently, these principles enable developers to write software that can evolve gracefully — even as requirements change or systems grow.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>📝Comparative Guide to Testing Management Tools with Real-World Code and Public Example Repositories</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Thu, 03 Jul 2025 01:04:16 +0000</pubDate>
      <link>https://forem.com/brunoenr/comparative-guide-to-testing-management-tools-with-real-world-code-and-public-example-repositories-3a00</link>
      <guid>https://forem.com/brunoenr/comparative-guide-to-testing-management-tools-with-real-world-code-and-public-example-repositories-3a00</guid>
      <description>&lt;p&gt;Managing software testing efficiently is key for successful projects. Testing Management Tools streamline planning, tracking, and automating test cases. In this article, you'll find:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Core concepts and benefits of test management tools&lt;/li&gt;
&lt;li&gt;A hands-on comparison of leading tools&lt;/li&gt;
&lt;li&gt;Real code snippets for API integration&lt;/li&gt;
&lt;li&gt;Public GitHub repositories for direct experimentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What Are Testing Management Tools?
&lt;/h2&gt;

&lt;p&gt;Testing Management Tools are platforms that help you create, organize, execute, and track software test cases and results. They support everything from manual to automated tests, integrate with CI/CD, and enable smooth collaboration across teams.&lt;/p&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Centralized test case management&lt;/li&gt;
&lt;li&gt;Manual and automated test execution&lt;/li&gt;
&lt;li&gt;Result tracking and dashboards&lt;/li&gt;
&lt;li&gt;Bug tracking integration (e.g., Jira, GitHub Issues)&lt;/li&gt;
&lt;li&gt;API access and CI/CD connectivity&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Top Testing Management Tools (with Code &amp;amp; Repos)
&lt;/h2&gt;

&lt;h2&gt;
  
  
  1. TestRail
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Commercial, enterprise-grade&lt;/li&gt;
&lt;li&gt;Rich test case management, Jira integration, powerful API&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;API Integration Example (Python):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import requests

url = "https://&amp;lt;your_domain&amp;gt;.testrail.io/index.php?/api/v2/get_cases/&amp;lt;project_id&amp;gt;"
headers = {"Content-Type": "application/json"}
response = requests.get(url, headers=headers, auth=("user", "api_key"))
print(response.json())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example repository:&lt;br&gt;
&lt;a href="https://github.com/gurock/testrail-api" rel="noopener noreferrer"&gt;https://github.com/gurock/testrail-api&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  2. TestLink
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Open source, widely used&lt;/li&gt;
&lt;li&gt;Classic web interface, bug tracker integration
Create a Test Case via XML-RPC:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import xmlrpc.client

server = xmlrpc.client.ServerProxy('http://localhost/testlink/lib/api/xmlrpc/v1/xmlrpc.php')
devKey = 'your_dev_key'
testprojectid = 1
testsuiteid = 1

case = server.tl.createTestCase(devKey, 'API Test Case', testprojectid, testsuiteid, 'Steps...', 'Expected results...')
print(case)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Public repo:&lt;br&gt;
&lt;a href="https://github.com/TestLinkOpenSourceTRMS/testlink-code" rel="noopener noreferrer"&gt;https://github.com/TestLinkOpenSourceTRMS/testlink-code&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Xray (for Jira)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Jira plugin, seamless native integration&lt;/li&gt;
&lt;li&gt;Advanced test case management, automation via REST API
Create a Test Issue via API:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -H "Content-Type: application/json" \
     -X POST -d '{"fields":{"project":{"key":"PROJ"},"summary":"API test case","issuetype":{"name":"Test"}}}' \
     -u user:api_token \
     https://&amp;lt;your_jira&amp;gt;.atlassian.net/rest/api/2/issue/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example repo (Xray + CI):&lt;br&gt;
&lt;a href="https://github.com/Xray-App/xray-junit5-gradle-example" rel="noopener noreferrer"&gt;https://github.com/Xray-App/xray-junit5-gradle-example&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Allure TestOps
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Modern platform with visual reporting and analytics&lt;/li&gt;
&lt;li&gt;Deep integration with popular automation frameworks (JUnit, Cypress, Playwright, etc.)
Integrate with Python (pytest + Allure):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import allure

@allure.title("Verify successful login")
def test_login():
    assert login("user", "password") is True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example repo:&lt;br&gt;
&lt;a href="https://github.com/allure-examples/allure-examples/tree/master/pytest" rel="noopener noreferrer"&gt;https://github.com/allure-examples/allure-examples/tree/master/pytest&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Example: Automating Test Management
&lt;/h2&gt;

&lt;p&gt;Suppose you have an automated test suite in Python (Pytest) and want to report results to Allure TestOps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Annotate your tests:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import allure

@allure.story('Login Functionality')
def test_login_success():
    assert login('admin', 'password') is True
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Run tests with Allure:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pytest --alluredir=./allure-results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Upload results to Allure TestOps (via CLI):
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;allurectl upload --endpoint https://your-allure-server --token &amp;lt;TOKEN&amp;gt; ./allure-results
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Complete repo for hands-on:&lt;br&gt;
&lt;a href="https://github.com/allure-examples/allure-examples" rel="noopener noreferrer"&gt;https://github.com/allure-examples/allure-examples&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Choosing the right test management tool depends on your project scale, budget, and tech stack.&lt;br&gt;
All the tools in this guide help teams to manage, automate, and gain insight into the testing process, from startups to enterprises.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Applying API Testing Frameworks real world examples</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Thu, 05 Jun 2025 15:31:58 +0000</pubDate>
      <link>https://forem.com/brunoenr/applying-api-testing-frameworks-real-world-examples-58p5</link>
      <guid>https://forem.com/brunoenr/applying-api-testing-frameworks-real-world-examples-58p5</guid>
      <description>&lt;p&gt;API testing is essential for ensuring the reliability and performance of web services. Various frameworks facilitate this process, each offering unique features and capabilities. This article explores several prominent API testing frameworks, providing real-world code examples to illustrate their usage. &lt;a href="https://alicealdaine.medium.com/top-10-api-testing-tools-rest-soap-services-5395cb03cfa9" rel="noopener noreferrer"&gt;Top 10 API Testing Tools for REST &amp;amp; SOAP Services&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Rest-Assured (Java)
&lt;/h2&gt;

&lt;p&gt;Rest-Assured is a Java-based library that simplifies testing RESTful APIs. Its syntax is expressive and BDD-like, making tests readable and maintainable.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This test sends a GET request to retrieve a post and asserts that the response has a status code of 200 and the userId is 1.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import io.restassured.RestAssured;
import org.junit.Test;
import static org.hamcrest.Matchers.*;

public class ApiTest {
    @Test
    public void testApiResponse() {
        RestAssured.given()
            .baseUri("https://jsonplaceholder.typicode.com")
        .when()
            .get("/posts/1")
        .then()
            .statusCode(200)
            .body("userId", equalTo(1));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Karate (Java)
&lt;/h2&gt;

&lt;p&gt;Karate is an open-source framework that combines API test automation, mocks, performance testing, and UI automation into a single framework. It uses a domain-specific language (DSL) to write tests in a readable format.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This feature file defines a scenario that sends a GET request and validates the response.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Feature: API Test

  Scenario: Validate API Response
    Given url 'https://jsonplaceholder.typicode.com/posts/1'
    When method GET
    Then status 200
    And match response.userId == 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Postman (JavaScript)
&lt;/h2&gt;

&lt;p&gt;Postman is a popular tool for API development and testing. It allows writing tests in JavaScript within its interface.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These tests check that the response status is 200 and that the response body contains a userId property.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

pm.test("Response has userId", function () {
    var jsonData = pm.response.json();
    pm.expect(jsonData).to.have.property("userId");
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. PyRestTest (Python)
&lt;/h2&gt;

&lt;p&gt;PyRestTest is a Python-based REST API testing tool that uses YAML for test case definitions. It's suitable for simple test scenarios.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This YAML file defines a test that sends a GET request to /users and validates the response status code and schema.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- config:
    - testset: "User API Tests"
    - base_url: "https://api.example.com"

- test:
    - name: "Get users"
    - url: "/users"
    - method: "GET"
    - headers: {'Content-Type': 'application/json'}
    - validators:
        - compare: {header: "status_code", comparator: "eq", expected: 200}
        - json_schema: {schema: {type: "array"}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. JMeter (Java)
&lt;/h2&gt;

&lt;p&gt;Apache JMeter is primarily used for performance testing but also supports functional API testing. It allows creating test plans with various samplers and assertions.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This JMeter test plan sends a GET request to /users and asserts that the first user's id is 1.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;HTTPSamplerProxy&amp;gt;
  &amp;lt;stringProp name="HTTPSampler.domain"&amp;gt;api.example.com&amp;lt;/stringProp&amp;gt;
  &amp;lt;stringProp name="HTTPSampler.path"&amp;gt;/users&amp;lt;/stringProp&amp;gt;
  &amp;lt;stringProp name="HTTPSampler.method"&amp;gt;GET&amp;lt;/stringProp&amp;gt;
  &amp;lt;HeaderManager&amp;gt;
    &amp;lt;collectionProp name="HeaderManager.headers"&amp;gt;
      &amp;lt;elementProp name=""&amp;gt;
        &amp;lt;stringProp name="Header.name"&amp;gt;Content-Type&amp;lt;/stringProp&amp;gt;
        &amp;lt;stringProp name="Header.value"&amp;gt;application/json&amp;lt;/stringProp&amp;gt;
      &amp;lt;/elementProp&amp;gt;
    &amp;lt;/collectionProp&amp;gt;
  &amp;lt;/HeaderManager&amp;gt;
  &amp;lt;JSONPathAssertion&amp;gt;
    &amp;lt;stringProp name="JSON_PATH"&amp;gt;$[0].id&amp;lt;/stringProp&amp;gt;
    &amp;lt;stringProp name="EXPECTED_VALUE"&amp;gt;1&amp;lt;/stringProp&amp;gt;
    &amp;lt;boolProp name="JSONVALIDATION"&amp;gt;true&amp;lt;/boolProp&amp;gt;
  &amp;lt;/JSONPathAssertion&amp;gt;
&amp;lt;/HTTPSamplerProxy&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Selecting the appropriate API testing framework depends on various factors, including the programming language, project requirements, and team expertise. Rest-Assured and Karate are excellent choices for Java developers, Postman offers a user-friendly interface for quick tests, PyRestTest is suitable for Python projects, and JMeter is ideal for performance testing scenarios. &lt;br&gt;
By leveraging these frameworks, teams can ensure their APIs are robust, reliable, and meet the desired specifications.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🛡️Secure Your CI Pipeline in Minutes with HuskyCI (SAST for Multiple Languages) huskyci</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Fri, 25 Apr 2025 16:19:46 +0000</pubDate>
      <link>https://forem.com/brunoenr/secure-your-ci-pipeline-in-minutes-with-huskyci-sast-for-multiple-languageshuskyci-2dfa</link>
      <guid>https://forem.com/brunoenr/secure-your-ci-pipeline-in-minutes-with-huskyci-sast-for-multiple-languageshuskyci-2dfa</guid>
      <description>&lt;p&gt;In today’s fast-paced software world, integrating security into your CI/CD pipeline is no longer optional — it’s essential. Fortunately, there are open-source tools that make it easier than ever. In this article, I’ll show you how to use HuskyCI, a powerful open-source tool that performs security tests automatically as part of your CI process and centralizes all results for easy analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧠 What is HuskyCI?&lt;/strong&gt;&lt;br&gt;
HuskyCI (Husky Continuous Integration) is an open-source tool developed by Globo.com that automates security testing in CI pipelines. It runs Static Application Security Testing (SAST) tools for multiple programming languages and provides a centralized view of vulnerabilities across your projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧪 It supports a wide range of tools and languages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python: Bandit, Safety&lt;/li&gt;
&lt;li&gt;Ruby: Brakeman&lt;/li&gt;
&lt;li&gt;JavaScript: NPM Audit, Yarn Audit&lt;/li&gt;
&lt;li&gt;Java: SpotBugs + FindSecBugs&lt;/li&gt;
&lt;li&gt;Go: Gosec&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;⚙️ Getting Started with HuskyCI&lt;/strong&gt;&lt;br&gt;
✅ Step 1: Clone the Repository&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/globocom/huskyCI.git
cd huskyCI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;✅ Step 2: Install with Docker and Docker Compose&lt;br&gt;
Make sure you have Docker and Docker Compose installed. Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;make install
make run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will spin up all necessary containers (API, workers, tools, database).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛠️ How to Use HuskyCI&lt;/strong&gt;&lt;br&gt;
Once up and running, trigger scans by sending your code to the HuskyCI API or by integrating it into your GitHub Actions or GitLab CI pipeline.&lt;/p&gt;

&lt;p&gt;Example scan via command-line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl -X POST http://localhost:8888/api/analysis \
-H "Content-Type: application/json" \
-d '{"repositoryURL":"https://github.com/.../huskyci-demo", "branch":"main"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HuskyCI will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone the repository&lt;/li&gt;
&lt;li&gt;Detect the programming language&lt;/li&gt;
&lt;li&gt;Run the appropriate SAST tools&lt;/li&gt;
&lt;li&gt;Store and return the results&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;📊 Sample Output&lt;/strong&gt;&lt;br&gt;
The response from the scan will include a list of findings, organized by tool and severity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Bandit": [
    {
      "file": "vulnerable_app.py",
      "line": 5,
      "issue": "Subprocess call with shell=True",
      "severity": "High"
    }
  ],
  "Safety": [],
  ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can then visualize or process this data as needed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🤖 GitHub Actions Integration&lt;/strong&gt;&lt;br&gt;
Want to trigger HuskyCI on each push or pull request? Here’s an example workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;name: HuskyCI Scan

on: [push, pull_request]

jobs:
  huskyci-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Trigger HuskyCI Scan
        run: |
          curl -X POST http://your-huskyci-instance/api/analysis \
          -H "Content-Type: application/json" \
          -d '{"repositoryURL":"...", "branch":"main"}'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure your CI runner has access to your HuskyCI instance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;📦 Demo Repository&lt;/strong&gt;&lt;br&gt;
👉 Check out the full working example here:&lt;br&gt;
🔗 &lt;a href="https://github.com/Brunoenr02/HuskyCIDemo" rel="noopener noreferrer"&gt;https://github.com/Brunoenr02/HuskyCIDemo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This repo includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A vulnerable Python script&lt;/li&gt;
&lt;li&gt;GitHub Actions workflow to trigger scans&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;✅ Conclusion&lt;/strong&gt;&lt;br&gt;
HuskyCI is a great solution if you want to automate security scans across multiple languages in your CI/CD workflows. It’s free, open-source, and battle-tested by major companies.&lt;/p&gt;

&lt;p&gt;Start integrating HuskyCI today — your pipeline will thank you, and your code will be safer!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🛡️Scan and Secure Your Mobile App with AppSweep (SAST for Android)</title>
      <dc:creator>Bruno Enrique ANCCO SUAÑA</dc:creator>
      <pubDate>Sun, 20 Apr 2025 23:02:07 +0000</pubDate>
      <link>https://forem.com/brunoenr/scan-and-secure-your-mobile-app-with-appsweep-sast-for-android-5h2d</link>
      <guid>https://forem.com/brunoenr/scan-and-secure-your-mobile-app-with-appsweep-sast-for-android-5h2d</guid>
      <description>&lt;p&gt;Securing your mobile app doesn’t have to be complicated. In this quick guide, I’ll show you how to use AppSweep, a free static analysis tool (SAST) from Guardsquare, to find vulnerabilities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🧠 What is SAST?&lt;/strong&gt;&lt;br&gt;
SAST (Static Application Security Testing) analyzes your source code without running it. It’s an essential technique to catch security issues early in your development process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔍 SAST helps you detect:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code injections&lt;/li&gt;
&lt;li&gt;Data leakage&lt;/li&gt;
&lt;li&gt;Misconfigurations&lt;/li&gt;
&lt;li&gt;Insecure coding practices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;🛡️ What is AppSweep?&lt;/strong&gt;&lt;br&gt;
AppSweep is a free security scanner by Guardsquare that analyzes Android apps. It scans your APK and gives you a detailed report with vulnerabilities, risks, and practical remediation tips.&lt;/p&gt;

&lt;p&gt;✅ Free and easy to use&lt;br&gt;
✅ CI/CD integration&lt;br&gt;
✅ Actionable recommendations&lt;br&gt;
✅ Based on OWASP MASVS, CWE, and industry standards&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🚀 How to Use AppSweep&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload your APK to the AppSweep website, or&lt;/li&gt;
&lt;li&gt;Use the official CLI to automate scans in your workflow.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You’ll get a full report with detailed findings and recommendations to help you fix issues fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;💻 Installing the CLI&lt;/strong&gt;&lt;br&gt;
To use AppSweep via the terminal or in CI pipelines, install the CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @guardsquare/appsweep-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Authenticate with your API key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appsweep auth --api-key YOUR_API_KEY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then scan your APK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appsweep scan --app-id YOUR_APP_ID ./path/to/your-app.apk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📦 CI/CD Integration&lt;/strong&gt;&lt;br&gt;
AppSweep works seamlessly with GitHub Actions, GitLab CI, Jenkins, and others.&lt;/p&gt;

&lt;p&gt;Example with GitHub Actions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Scan with AppSweep
  run: |
    npm install -g @guardsquare/appsweep-cli
    appsweep auth --api-key ${{ secrets.APPSWEEP_API_KEY }}
    appsweep scan --app-id ${{ secrets.APPSWEEP_APP_ID }} ./build/outputs/apk/release/app-release.apk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📊 Custom Reports&lt;/strong&gt;&lt;br&gt;
Export results in JSON for further processing or integration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;appsweep scan --app-id ... --output report.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📦 Demo Repository&lt;/strong&gt;&lt;br&gt;
👉 Check out the full working example here:&lt;br&gt;
🔗 &lt;a href="https://github.com/Brunoenr02/AppSweepDemo" rel="noopener noreferrer"&gt;https://github.com/Brunoenr02/AppSweepDemo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;✅ Conclusion&lt;/strong&gt;&lt;br&gt;
With tools like AppSweep, adding security checks to your mobile development workflow is easy, fast, and free. Don’t wait for production to find critical issues—scan early and often!&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
