<?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>DEV Community: Abel Fernando PACOMPIA ORTIZ</title>
    <description>The latest articles on DEV Community by Abel Fernando PACOMPIA ORTIZ (@abel_fernandopacompiaor).</description>
    <link>https://dev.to/abel_fernandopacompiaor</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4004729%2Fdbff5f55-6b75-4cd3-9755-b491f268dd5c.png</url>
      <title>DEV Community: Abel Fernando PACOMPIA ORTIZ</title>
      <link>https://dev.to/abel_fernandopacompiaor</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abel_fernandopacompiaor"/>
    <language>en</language>
    <item>
      <title># SQL AI Database Solutions: Code and Real-World Examples</title>
      <dc:creator>Abel Fernando PACOMPIA ORTIZ</dc:creator>
      <pubDate>Sun, 05 Jul 2026 03:55:02 +0000</pubDate>
      <link>https://dev.to/abel_fernandopacompiaor/-sql-ai-database-solutions-code-and-real-world-examples-2mpj</link>
      <guid>https://dev.to/abel_fernandopacompiaor/-sql-ai-database-solutions-code-and-real-world-examples-2mpj</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Public Example Repository:&lt;/strong&gt; &lt;a href="https://github.com/Abel-GG-777/sql-ai-database-solutions" rel="noopener noreferrer"&gt;https://github.com/Abel-GG-777/sql-ai-database-solutions&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;SQL AI Database Solutions combine database systems with artificial intelligence techniques that allow users to ask questions in natural language and receive SQL queries or query results. This article explains the concept of Text-to-SQL, why AI is useful for database querying, and how a small Python application can translate natural language into safe SQLite &lt;code&gt;SELECT&lt;/code&gt; statements. The repository includes a working Streamlit demo, a realistic sample database, code examples, and tests. It also discusses real-world use cases, benefits, limitations, risks, and security considerations for production systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Databases are essential in modern organizations because they store sales records, customer information, student data, inventory levels, support tickets, and many other operational facts. However, many users who need answers from a database do not know SQL. A sales manager may ask, "Which products generated the most revenue this month?" A student services worker may ask, "Which active students are enrolled in Computer Science?" These questions are easy for humans to understand, but they normally require technical SQL knowledge.&lt;/p&gt;

&lt;p&gt;SQL AI Database Solutions address this gap by using artificial intelligence to help users communicate with databases in natural language. The goal is not to remove database professionals, but to make data access faster and more understandable while preserving security and correctness.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are SQL AI Database Solutions?
&lt;/h2&gt;

&lt;p&gt;SQL AI Database Solutions are systems that use AI models, rules, or hybrid methods to help users interact with relational databases. In a typical solution, the user writes a natural language question, the system reads the database schema, an AI component generates an SQL query, and the database executes the query.&lt;/p&gt;

&lt;p&gt;The solution may return the generated SQL, the query results, or both. In educational and professional environments, showing the generated SQL is useful because users can learn how natural language maps to database logic. It also supports transparency, review, and debugging.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is Text-to-SQL?
&lt;/h2&gt;

&lt;p&gt;Text-to-SQL is the task of converting natural language into SQL. For example:&lt;/p&gt;

&lt;p&gt;Natural language question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which products are low in stock?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generated SQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt;
    &lt;span class="n"&gt;sku&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;stock_quantity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reorder_level&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;products&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;stock_quantity&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;reorder_level&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;stock_quantity&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modern Text-to-SQL systems often use large language models trained or prompted to understand schemas, table relationships, and user intent. Some systems use general language models, while others use specialized models available through platforms such as Hugging Face.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why AI Is Useful for Database Querying
&lt;/h2&gt;

&lt;p&gt;AI is useful for database querying because it can reduce the technical barrier between users and data. A non-technical user can ask a question in normal language instead of memorizing SQL syntax. AI can also speed up the work of analysts by creating first drafts of queries, suggesting joins, and helping explore unfamiliar schemas.&lt;/p&gt;

&lt;p&gt;AI also supports education. Students can compare their natural language questions with generated SQL and understand how tables, filters, grouping, and ordering work. This repository supports that learning goal by showing the generated query before displaying the result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Architecture of the Demo Application
&lt;/h2&gt;

&lt;p&gt;The demo application uses a simple and safe architecture:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The user enters a natural language question in Streamlit.&lt;/li&gt;
&lt;li&gt;The application connects to a local SQLite database.&lt;/li&gt;
&lt;li&gt;The schema reader extracts table and column information.&lt;/li&gt;
&lt;li&gt;The query generator creates an SQL query.&lt;/li&gt;
&lt;li&gt;The validator allows only &lt;code&gt;SELECT&lt;/code&gt; queries and blocks dangerous keywords.&lt;/li&gt;
&lt;li&gt;The query executor runs the query.&lt;/li&gt;
&lt;li&gt;Streamlit displays the generated SQL and the results.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The main files are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app.py&lt;/code&gt;: Streamlit user interface.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/database.py&lt;/code&gt;: SQLite connection and database creation.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/schema_reader.py&lt;/code&gt;: Table and column extraction.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/query_generator.py&lt;/code&gt;: Optional Hugging Face generation and rule-based fallback.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/query_executor.py&lt;/code&gt;: SQL validation and execution.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;data/seed_data.sql&lt;/code&gt;: Sample database schema and realistic data.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Examples
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Database Connection
&lt;/h3&gt;

&lt;p&gt;The database module opens a SQLite connection and configures rows so they can be converted into dictionaries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="n"&gt;DEFAULT_DB_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;data/sample.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_connection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DEFAULT_DB_PATH&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;db_path&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;row_factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Row&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SQLite is used because it is local, portable, and does not require exposing credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema Extraction
&lt;/h3&gt;

&lt;p&gt;The application reads the database schema so the query generator can understand available tables and columns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;list_tables&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        SELECT name
        FROM sqlite_master
        WHERE type = &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;table&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;
          AND name NOT LIKE &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sqlite_%&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;
        ORDER BY name;
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;name&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extracted schema can be formatted as prompt context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;products(product_id INTEGER, sku TEXT, name TEXT, category TEXT, unit_price REAL)
sales(sale_id INTEGER, customer_id INTEGER, product_id INTEGER, sale_date TEXT)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Natural Language Prompt Input
&lt;/h3&gt;

&lt;p&gt;In the Streamlit interface, users write a natural language question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;question&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text_area&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Ask a question about the sample database&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Which products are low in stock?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the interface accessible to users who do not know SQL.&lt;/p&gt;

&lt;h3&gt;
  
  
  SQL Query Generation
&lt;/h3&gt;

&lt;p&gt;The demo supports optional Hugging Face integration using environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;HF_API_TOKEN&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;_generate_with_hugging_face&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;schema_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;generate_rule_based_sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;question&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no token is configured, the app uses a rule-based fallback:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;low&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;normalized_question&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stock&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;normalized_question&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
    SELECT sku, name, category, stock_quantity, reorder_level
    FROM products
    WHERE stock_quantity &amp;lt;= reorder_level
    ORDER BY stock_quantity ASC
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This keeps the classroom demo functional without paid services or external APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  SQL Validation
&lt;/h3&gt;

&lt;p&gt;The demo limits generated SQL to &lt;code&gt;SELECT&lt;/code&gt; statements only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;first_token&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;SqlValidationError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Only SELECT queries are allowed.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also blocks dangerous keywords:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;BLOCKED_SQL_KEYWORDS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ALTER&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CREATE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DELETE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DROP&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;INSERT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;REPLACE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;TRUNCATE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UPDATE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;VACUUM&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is basic validation for a sample project. It is not enough for production environments.&lt;/p&gt;

&lt;h3&gt;
  
  
  SQL Query Execution
&lt;/h3&gt;

&lt;p&gt;The executor validates the SQL before running it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;execute_select_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;safe_sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;validate_sql&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;cursor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe_sql&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Result Display
&lt;/h3&gt;

&lt;p&gt;Streamlit displays the generated SQL and the returned rows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;code&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;safe_sql&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sql&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dataframe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pd&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DataFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;use_container_width&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This design helps users see both the query and the data result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Business Dashboard Queries
&lt;/h3&gt;

&lt;p&gt;A manager can ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What are the top selling products by revenue?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system can generate a query that joins &lt;code&gt;sales&lt;/code&gt; and &lt;code&gt;products&lt;/code&gt;, groups by product, and orders by revenue. This supports quick dashboard exploration.&lt;/p&gt;

&lt;h3&gt;
  
  
  Student Records Search
&lt;/h3&gt;

&lt;p&gt;A university office can ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find active students in Computer Science.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system can filter the &lt;code&gt;students&lt;/code&gt; table by program and enrollment status. This is useful for academic advising, reporting, and enrollment management.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sales Analysis
&lt;/h3&gt;

&lt;p&gt;A sales analyst can ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Show total sales by month.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SQL query can group records by month and calculate revenue. This helps identify trends over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Inventory Management
&lt;/h3&gt;

&lt;p&gt;An operations employee can ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Which products are low in stock?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query can compare &lt;code&gt;stock_quantity&lt;/code&gt; with &lt;code&gt;reorder_level&lt;/code&gt;. This supports restocking decisions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Customer Support Data Extraction
&lt;/h3&gt;

&lt;p&gt;A support supervisor can ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;List open high priority support tickets.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The system can join tickets with customers and filter by status and priority. This helps teams prioritize urgent cases.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advantages
&lt;/h2&gt;

&lt;p&gt;SQL AI Database Solutions provide several advantages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They make databases easier for non-technical users.&lt;/li&gt;
&lt;li&gt;They reduce the time needed to write common queries.&lt;/li&gt;
&lt;li&gt;They help analysts explore unfamiliar schemas.&lt;/li&gt;
&lt;li&gt;They can support training and SQL education.&lt;/li&gt;
&lt;li&gt;They improve transparency when generated SQL is shown to the user.&lt;/li&gt;
&lt;li&gt;They can be integrated into dashboards, internal tools, and support systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Limitations and Risks
&lt;/h2&gt;

&lt;p&gt;AI-generated SQL can be incorrect. It may choose the wrong table, misunderstand a business term, miss a filter, or create an expensive query. Natural language can also be ambiguous. For example, "best customers" could mean highest revenue, highest number of purchases, or highest satisfaction score.&lt;/p&gt;

&lt;p&gt;Large language models can also hallucinate columns or tables that do not exist. Even when the SQL is valid, the result may not answer the user's actual question. For this reason, generated SQL should be reviewed, especially when used for financial, academic, legal, or operational decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security Considerations
&lt;/h2&gt;

&lt;p&gt;Security is one of the most important topics in SQL AI systems. A production system should not simply generate SQL and run it with full database permissions. It should use a dedicated read-only database account, strict access control, audit logging, query limits, and strong validation.&lt;/p&gt;

&lt;p&gt;This demo includes basic safety rules:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQLite is used locally.&lt;/li&gt;
&lt;li&gt;No database credentials are required.&lt;/li&gt;
&lt;li&gt;Only &lt;code&gt;SELECT&lt;/code&gt; statements are allowed.&lt;/li&gt;
&lt;li&gt;Dangerous keywords such as &lt;code&gt;DROP&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;ALTER&lt;/code&gt;, and &lt;code&gt;TRUNCATE&lt;/code&gt; are blocked.&lt;/li&gt;
&lt;li&gt;Hugging Face integration is optional and controlled by environment variables.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Production systems need stronger validation, permissions, logging, monitoring, rate limiting, and human review workflows. Sensitive data should be protected with masking, role-based access, and privacy rules.&lt;/p&gt;

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

&lt;p&gt;SQL AI Database Solutions can make data access more natural, faster, and more inclusive. By combining natural language input, schema extraction, Text-to-SQL generation, validation, and result display, users can interact with relational databases without writing SQL manually.&lt;/p&gt;

&lt;p&gt;This repository demonstrates the core idea using Python, Streamlit, and SQLite. It includes a local rule-based fallback so the project works without an API key, and it includes optional Hugging Face integration for experimentation with AI models. The project is intentionally simple, but it shows the foundation of real-world systems that help people talk to databases using natural language.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Hugging Face. "Models." &lt;a href="https://huggingface.co/models" rel="noopener noreferrer"&gt;https://huggingface.co/models&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Streamlit Documentation. &lt;a href="https://docs.streamlit.io/" rel="noopener noreferrer"&gt;https://docs.streamlit.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;SQLite Documentation. &lt;a href="https://www.sqlite.org/docs.html" rel="noopener noreferrer"&gt;https://www.sqlite.org/docs.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Python sqlite3 Documentation. &lt;a href="https://docs.python.org/3/library/sqlite3.html" rel="noopener noreferrer"&gt;https://docs.python.org/3/library/sqlite3.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Spider: A Large-Scale Human-Labeled Dataset for Complex and Cross-Domain Semantic Parsing and Text-to-SQL Task. &lt;a href="https://yale-lily.github.io/spider" rel="noopener noreferrer"&gt;https://yale-lily.github.io/spider&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Defog SQLCoder model collection. &lt;a href="https://huggingface.co/defog" rel="noopener noreferrer"&gt;https://huggingface.co/defog&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>sql</category>
      <category>python</category>
      <category>database</category>
    </item>
    <item>
      <title>Testing Management Tools Comparative Study</title>
      <dc:creator>Abel Fernando PACOMPIA ORTIZ</dc:creator>
      <pubDate>Sun, 05 Jul 2026 03:21:19 +0000</pubDate>
      <link>https://dev.to/abel_fernandopacompiaor/testing-management-tools-comparative-study-32i5</link>
      <guid>https://dev.to/abel_fernandopacompiaor/testing-management-tools-comparative-study-32i5</guid>
      <description>&lt;p&gt;Public example repository: &lt;a href="https://github.com/Abel-GG-777/testing-management-tools-comparison" rel="noopener noreferrer"&gt;https://github.com/Abel-GG-777/testing-management-tools-comparison&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstract
&lt;/h2&gt;

&lt;p&gt;Testing management tools help software teams automate quality checks, run repeatable pipelines, publish feedback, and reduce the risk of releasing broken software. This article compares nine widely used tools: GitHub Actions, GitLab CI/CD, Jenkins, CircleCI, TeamCity, Travis CI, Bitbucket Pipelines, Tekton, and Harness. The comparison includes technical characteristics, advantages, disadvantages, real-world use cases, and configuration examples that run the sample Python unit tests included in this repository.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sample Project Used for the Examples
&lt;/h2&gt;

&lt;p&gt;The repository includes a small Python application in &lt;code&gt;sample-app/&lt;/code&gt;. The application calculates a software quality score from testing metrics. The same basic command is used by all pipeline examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;sample-app
&lt;span class="nv"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;src python &lt;span class="nt"&gt;-m&lt;/span&gt; unittest discover &lt;span class="nt"&gt;-s&lt;/span&gt; tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives every platform a common testing scenario: checkout the repository, prepare a Python runtime, and execute automated unit tests.&lt;/p&gt;

&lt;h2&gt;
  
  
  Comparison Table
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Open source or commercial&lt;/th&gt;
&lt;th&gt;Cloud or self-hosted&lt;/th&gt;
&lt;th&gt;Language support&lt;/th&gt;
&lt;th&gt;Ease of use&lt;/th&gt;
&lt;th&gt;Scalability&lt;/th&gt;
&lt;th&gt;Best use case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;Commercial platform with free tiers; many open source actions&lt;/td&gt;
&lt;td&gt;GitHub-hosted and self-hosted runners&lt;/td&gt;
&lt;td&gt;Any language supported by runners or containers&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;GitHub-native automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitLab CI/CD&lt;/td&gt;
&lt;td&gt;Open core plus commercial tiers&lt;/td&gt;
&lt;td&gt;GitLab.com and self-managed&lt;/td&gt;
&lt;td&gt;Any language through runners and images&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Integrated DevSecOps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Jenkins&lt;/td&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;Self-hosted&lt;/td&gt;
&lt;td&gt;Very broad through plugins and agents&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;td&gt;Custom enterprise automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CircleCI&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;Cloud and self-hosted runners&lt;/td&gt;
&lt;td&gt;Broad container and VM support&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Fast containerized CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TeamCity&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;Cloud and self-hosted&lt;/td&gt;
&lt;td&gt;Broad build runner support&lt;/td&gt;
&lt;td&gt;Medium-high&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Enterprise build chains&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Travis CI&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;Cloud&lt;/td&gt;
&lt;td&gt;Many language environments&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Simple hosted CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Pipelines&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;Bitbucket Cloud&lt;/td&gt;
&lt;td&gt;Any language through Docker images&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Medium-high&lt;/td&gt;
&lt;td&gt;Bitbucket-native automation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tekton&lt;/td&gt;
&lt;td&gt;Open source&lt;/td&gt;
&lt;td&gt;Kubernetes-native&lt;/td&gt;
&lt;td&gt;Any language through containers&lt;/td&gt;
&lt;td&gt;Medium&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;td&gt;Platform engineering on Kubernetes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harness&lt;/td&gt;
&lt;td&gt;Commercial&lt;/td&gt;
&lt;td&gt;SaaS and self-managed options&lt;/td&gt;
&lt;td&gt;Broad CI and CD integrations&lt;/td&gt;
&lt;td&gt;Medium-high&lt;/td&gt;
&lt;td&gt;Very high&lt;/td&gt;
&lt;td&gt;Enterprise delivery governance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  1. GitHub Actions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;GitHub Actions is GitHub's automation platform. Workflows are stored as YAML files under &lt;code&gt;.github/workflows/&lt;/code&gt; and are triggered by events such as pushes, pull requests, schedules, releases, or manual dispatches. Because it is built into GitHub, it is especially convenient for repositories hosted there.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Event-driven workflows for repository activity.&lt;/li&gt;
&lt;li&gt;GitHub-hosted runners for Linux, Windows, and macOS.&lt;/li&gt;
&lt;li&gt;Self-hosted runners for private infrastructure.&lt;/li&gt;
&lt;li&gt;Matrix builds for testing multiple versions or environments.&lt;/li&gt;
&lt;li&gt;Marketplace actions for reusable automation.&lt;/li&gt;
&lt;li&gt;Secrets, environments, and permissions for controlled execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Very easy to adopt in GitHub repositories.&lt;/li&gt;
&lt;li&gt;Strong ecosystem of reusable actions.&lt;/li&gt;
&lt;li&gt;Good integration with pull requests, code review, releases, and repository permissions.&lt;/li&gt;
&lt;li&gt;YAML configuration is version-controlled with the source code.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Best experience is tied to GitHub.&lt;/li&gt;
&lt;li&gt;Third-party marketplace actions require security review.&lt;/li&gt;
&lt;li&gt;Complex workflows can become difficult to maintain.&lt;/li&gt;
&lt;li&gt;Usage minutes and larger runners may create cost concerns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Running unit tests and linters on every pull request.&lt;/li&gt;
&lt;li&gt;Publishing packages after a tagged release.&lt;/li&gt;
&lt;li&gt;Building Docker images and pushing them to a registry.&lt;/li&gt;
&lt;li&gt;Deploying static sites or cloud services after approval.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Python CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;defaults&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;working-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sample-app&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-python@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;python-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.12"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python -m unittest discover -s tests&lt;/span&gt;
        &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;src&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this repository, the complete workflow is available at &lt;code&gt;.github/workflows/ci.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. GitLab CI/CD
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;GitLab CI/CD is GitLab's integrated pipeline system. It uses a &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file at the repository root and executes jobs through GitLab Runners. It is part of a broader DevSecOps platform that can include issues, merge requests, security scanning, artifacts, environments, and deployments.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pipeline stages and jobs defined in YAML.&lt;/li&gt;
&lt;li&gt;Shared, group, project, and self-managed runners.&lt;/li&gt;
&lt;li&gt;Docker image support for job environments.&lt;/li&gt;
&lt;li&gt;Artifacts, caches, environments, and deployments.&lt;/li&gt;
&lt;li&gt;Parent-child pipelines and multi-project pipelines.&lt;/li&gt;
&lt;li&gt;Security and compliance features in GitLab tiers.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strong integration across planning, source control, testing, and deployment.&lt;/li&gt;
&lt;li&gt;Flexible runner architecture.&lt;/li&gt;
&lt;li&gt;Good support for monorepos and complex release workflows.&lt;/li&gt;
&lt;li&gt;Built-in security scanning options.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Most valuable when a team uses GitLab as its main platform.&lt;/li&gt;
&lt;li&gt;Advanced enterprise features may require paid tiers.&lt;/li&gt;
&lt;li&gt;YAML files can become large in complex organizations.&lt;/li&gt;
&lt;li&gt;Runner management requires operational discipline.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testing merge requests before approval.&lt;/li&gt;
&lt;li&gt;Building container images and deploying to Kubernetes.&lt;/li&gt;
&lt;li&gt;Running security scanning as part of a DevSecOps pipeline.&lt;/li&gt;
&lt;li&gt;Coordinating multiple services with child pipelines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;

&lt;span class="na"&gt;python_tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
  &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python:3.12-slim&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;PYTHONPATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$CI_PROJECT_DIR/sample-app/src"&lt;/span&gt;
  &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cd sample-app&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;python -m unittest discover -s tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository includes this example in &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Jenkins
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Jenkins is an open source automation server with a long history in continuous integration. It is usually self-hosted and can be extended through a large plugin ecosystem. Jenkins pipelines are commonly written in a &lt;code&gt;Jenkinsfile&lt;/code&gt; using declarative or scripted pipeline syntax.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Declarative and scripted pipelines.&lt;/li&gt;
&lt;li&gt;Large plugin ecosystem.&lt;/li&gt;
&lt;li&gt;Distributed builds through agents.&lt;/li&gt;
&lt;li&gt;Integration with many source control, testing, artifact, and deployment systems.&lt;/li&gt;
&lt;li&gt;Credentials management and role-based access through plugins.&lt;/li&gt;
&lt;li&gt;Support for custom infrastructure and legacy systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Extremely flexible and customizable.&lt;/li&gt;
&lt;li&gt;Open source and widely adopted.&lt;/li&gt;
&lt;li&gt;Strong for enterprises with special infrastructure needs.&lt;/li&gt;
&lt;li&gt;Can integrate with older tools that modern SaaS products may not support.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Requires server administration, plugin maintenance, backups, and security patching.&lt;/li&gt;
&lt;li&gt;Plugin conflicts can create maintenance risks.&lt;/li&gt;
&lt;li&gt;User experience is less modern than many hosted platforms.&lt;/li&gt;
&lt;li&gt;Scaling requires careful architecture.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise CI/CD across multiple programming languages.&lt;/li&gt;
&lt;li&gt;Legacy application builds that require custom agents.&lt;/li&gt;
&lt;li&gt;Highly customized deployment workflows.&lt;/li&gt;
&lt;li&gt;Internal automation beyond software builds.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;pipeline&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;docker&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;image&lt;/span&gt; &lt;span class="s1"&gt;'python:3.12-slim'&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;stage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Unit Tests'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;steps&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sample-app'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;withEnv&lt;/span&gt;&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'PYTHONPATH=src'&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="n"&gt;sh&lt;/span&gt; &lt;span class="s1"&gt;'python -m unittest discover -s tests'&lt;/span&gt;
                    &lt;span class="o"&gt;}&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The complete Jenkins example is available in &lt;code&gt;Jenkinsfile&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. CircleCI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;CircleCI is a hosted CI/CD platform focused on fast builds, reusable configuration, and container-based execution. Configuration is stored in &lt;code&gt;.circleci/config.yml&lt;/code&gt;. CircleCI also supports reusable packages called orbs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker, machine, macOS, and Windows execution environments.&lt;/li&gt;
&lt;li&gt;Workflows that coordinate multiple jobs.&lt;/li&gt;
&lt;li&gt;Dependency caching and workspaces.&lt;/li&gt;
&lt;li&gt;Parallelism and test splitting.&lt;/li&gt;
&lt;li&gt;Orbs for reusable integrations.&lt;/li&gt;
&lt;li&gt;Cloud service with self-hosted runner options.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strong developer experience for containerized projects.&lt;/li&gt;
&lt;li&gt;Good caching and parallel execution features.&lt;/li&gt;
&lt;li&gt;Orbs reduce repeated configuration.&lt;/li&gt;
&lt;li&gt;Useful insights for build performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Commercial pricing can matter for larger teams.&lt;/li&gt;
&lt;li&gt;Configuration is specific to CircleCI.&lt;/li&gt;
&lt;li&gt;Advanced workflows can require learning platform-specific concepts.&lt;/li&gt;
&lt;li&gt;Some environments have resource limits depending on plan.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Fast test pipelines for web services.&lt;/li&gt;
&lt;li&gt;Container image builds.&lt;/li&gt;
&lt;li&gt;Mobile application builds.&lt;/li&gt;
&lt;li&gt;Multi-job workflows with approvals before deployment.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.1&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;docker&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cimg/python:3.12&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;checkout&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Python unit tests&lt;/span&gt;
          &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;cd sample-app&lt;/span&gt;
            &lt;span class="s"&gt;PYTHONPATH=src python -m unittest discover -s tests&lt;/span&gt;

&lt;span class="na"&gt;workflows&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test_sample_app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository includes this file at &lt;code&gt;.circleci/config.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. TeamCity
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;TeamCity is JetBrains' CI/CD product. It provides a strong web interface, build chains, project templates, test reporting, and configuration as code through Kotlin DSL. It is available as TeamCity Cloud and TeamCity On-Premises.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Build configurations and build chains.&lt;/li&gt;
&lt;li&gt;Kotlin DSL for version-controlled configuration.&lt;/li&gt;
&lt;li&gt;Rich test reporting and build history.&lt;/li&gt;
&lt;li&gt;Build agents for multiple environments.&lt;/li&gt;
&lt;li&gt;Templates for repeated project patterns.&lt;/li&gt;
&lt;li&gt;Strong IDE-style support for Kotlin configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Excellent visualization of build chains and test results.&lt;/li&gt;
&lt;li&gt;Kotlin DSL is typed and maintainable for complex setups.&lt;/li&gt;
&lt;li&gt;Strong enterprise build management capabilities.&lt;/li&gt;
&lt;li&gt;Good fit for teams already using JetBrains tools.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Commercial licensing may be required.&lt;/li&gt;
&lt;li&gt;Less common in open source repositories than GitHub Actions or GitLab CI/CD.&lt;/li&gt;
&lt;li&gt;Kotlin DSL requires some Kotlin familiarity.&lt;/li&gt;
&lt;li&gt;On-premises deployments require server and agent maintenance.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise build pipelines with multiple dependent components.&lt;/li&gt;
&lt;li&gt;Projects requiring detailed test trend history.&lt;/li&gt;
&lt;li&gt;Organizations using JetBrains IDEs and TeamCity agents.&lt;/li&gt;
&lt;li&gt;Complex build chains with shared templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jetbrains.buildServer.configs.kotlin.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;jetbrains.buildServer.configs.kotlin.buildSteps.script&lt;/span&gt;

&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2025.11"&lt;/span&gt;

&lt;span class="nf"&gt;project&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;buildType&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"SampleAppTests"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Sample App Unit Tests"&lt;/span&gt;

        &lt;span class="nf"&gt;steps&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nf"&gt;script&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Run Python unit tests"&lt;/span&gt;
                &lt;span class="n"&gt;scriptContent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"""
                    cd sample-app
                    python -m unittest discover -s tests
                """&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trimIndent&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="nf"&gt;param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"env.PYTHONPATH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"src"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository includes a TeamCity Kotlin DSL example in &lt;code&gt;teamcity/kotlin-config.kt&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Travis CI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Travis CI is a hosted continuous integration service known for simple &lt;code&gt;.travis.yml&lt;/code&gt; configuration files. It became popular in open source communities because repositories could enable CI quickly with minimal setup.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;YAML configuration through &lt;code&gt;.travis.yml&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Built-in support for many programming languages.&lt;/li&gt;
&lt;li&gt;Build stages and job matrices.&lt;/li&gt;
&lt;li&gt;Branch and pull request builds.&lt;/li&gt;
&lt;li&gt;Deployment integrations.&lt;/li&gt;
&lt;li&gt;Hosted build environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Simple for small and medium projects.&lt;/li&gt;
&lt;li&gt;Easy language-specific setup.&lt;/li&gt;
&lt;li&gt;Good for straightforward test pipelines.&lt;/li&gt;
&lt;li&gt;Configuration is easy to read.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Less flexible than Jenkins or Tekton for custom infrastructure.&lt;/li&gt;
&lt;li&gt;Commercial model and usage limits may affect projects.&lt;/li&gt;
&lt;li&gt;Smaller modern ecosystem than GitHub Actions.&lt;/li&gt;
&lt;li&gt;Advanced deployment workflows may require more custom scripting.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Running tests for open source libraries.&lt;/li&gt;
&lt;li&gt;Validating pull requests in small repositories.&lt;/li&gt;
&lt;li&gt;Simple release automation.&lt;/li&gt;
&lt;li&gt;Multi-version language testing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python&lt;/span&gt;
&lt;span class="na"&gt;python&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.10"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.11"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.12"&lt;/span&gt;

&lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cd sample-app&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PYTHONPATH=src python -m unittest discover -s tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository includes this example in &lt;code&gt;.travis.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Bitbucket Pipelines
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Bitbucket Pipelines is the CI/CD service built into Bitbucket Cloud. Configuration is stored in &lt;code&gt;bitbucket-pipelines.yml&lt;/code&gt;, and builds commonly run inside Docker images. It is a natural option for teams that host code in Bitbucket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;YAML pipelines stored in the repository.&lt;/li&gt;
&lt;li&gt;Docker image based build steps.&lt;/li&gt;
&lt;li&gt;Branch, pull request, tag, and custom pipelines.&lt;/li&gt;
&lt;li&gt;Built-in caches and artifacts.&lt;/li&gt;
&lt;li&gt;Deployment environments.&lt;/li&gt;
&lt;li&gt;Integration with Bitbucket pull requests and permissions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Very convenient for Bitbucket Cloud repositories.&lt;/li&gt;
&lt;li&gt;Simple Docker-based execution model.&lt;/li&gt;
&lt;li&gt;Good integration with Atlassian tools.&lt;/li&gt;
&lt;li&gt;Easy to understand for small projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Closely tied to Bitbucket Cloud.&lt;/li&gt;
&lt;li&gt;Not as flexible as Jenkins for custom infrastructure.&lt;/li&gt;
&lt;li&gt;Large pipelines may need plan upgrades.&lt;/li&gt;
&lt;li&gt;Smaller marketplace than GitHub Actions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Testing pull requests in Bitbucket.&lt;/li&gt;
&lt;li&gt;Deploying to staging or production after branch merges.&lt;/li&gt;
&lt;li&gt;Building Docker images for services.&lt;/li&gt;
&lt;li&gt;Running quality checks for Atlassian-centered teams.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python:3.12-slim&lt;/span&gt;

&lt;span class="na"&gt;pipelines&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run unit tests&lt;/span&gt;
        &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;cd sample-app&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PYTHONPATH=src python -m unittest discover -s tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository includes this example in &lt;code&gt;bitbucket-pipelines.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Tekton
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Tekton is an open source framework for creating CI/CD systems on Kubernetes. Instead of being a single hosted product, it provides Kubernetes custom resources such as &lt;code&gt;Task&lt;/code&gt;, &lt;code&gt;Pipeline&lt;/code&gt;, and &lt;code&gt;PipelineRun&lt;/code&gt;. Tekton is often used by platform teams to build reusable CI/CD services.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Kubernetes-native custom resources.&lt;/li&gt;
&lt;li&gt;Reusable tasks and pipelines.&lt;/li&gt;
&lt;li&gt;Container-based execution for every step.&lt;/li&gt;
&lt;li&gt;Workspaces for shared data.&lt;/li&gt;
&lt;li&gt;Parameters and results for pipeline composition.&lt;/li&gt;
&lt;li&gt;Strong fit with GitOps and cloud-native infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Open source and highly extensible.&lt;/li&gt;
&lt;li&gt;Scales with Kubernetes.&lt;/li&gt;
&lt;li&gt;Good for platform engineering and internal developer platforms.&lt;/li&gt;
&lt;li&gt;Avoids being tied to a single SaaS CI provider.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Requires Kubernetes knowledge.&lt;/li&gt;
&lt;li&gt;More complex initial setup than hosted CI tools.&lt;/li&gt;
&lt;li&gt;User interface and developer experience depend on additional tooling.&lt;/li&gt;
&lt;li&gt;Teams must operate cluster resources and security policies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Building internal CI/CD platforms.&lt;/li&gt;
&lt;li&gt;Running pipelines close to Kubernetes workloads.&lt;/li&gt;
&lt;li&gt;Standardizing reusable build tasks across teams.&lt;/li&gt;
&lt;li&gt;Cloud-native delivery with GitOps systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;apiVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tekton.dev/v1&lt;/span&gt;
&lt;span class="na"&gt;kind&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Task&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;run-python-tests&lt;/span&gt;
&lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workspaces&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;source&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unit-tests&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;python:3.12-slim&lt;/span&gt;
      &lt;span class="na"&gt;workingDir&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;$(workspaces.source.path)/repo/sample-app"&lt;/span&gt;
      &lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;PYTHONPATH&lt;/span&gt;
          &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;src&lt;/span&gt;
      &lt;span class="na"&gt;script&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;#!/usr/bin/env sh&lt;/span&gt;
        &lt;span class="s"&gt;set -eu&lt;/span&gt;
        &lt;span class="s"&gt;python -m unittest discover -s tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The complete Tekton example is available in &lt;code&gt;tekton/pipeline.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Harness
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Overview
&lt;/h3&gt;

&lt;p&gt;Harness is a commercial software delivery platform that includes CI, CD, feature flags, cloud cost management, governance, and verification features. It focuses on enterprise-scale delivery with templates, approvals, policies, and deployment visibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Main Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;CI and CD pipeline stages.&lt;/li&gt;
&lt;li&gt;YAML-based pipeline definitions.&lt;/li&gt;
&lt;li&gt;Connectors for Git, container registries, cloud providers, and Kubernetes.&lt;/li&gt;
&lt;li&gt;Templates, approval gates, and governance features.&lt;/li&gt;
&lt;li&gt;Deployment verification and rollback support.&lt;/li&gt;
&lt;li&gt;Secrets management and role-based access controls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Strong enterprise governance and deployment controls.&lt;/li&gt;
&lt;li&gt;Good support for complex multi-environment delivery.&lt;/li&gt;
&lt;li&gt;Useful for organizations that need approvals, audit trails, and templates.&lt;/li&gt;
&lt;li&gt;Combines testing automation with release management.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Disadvantages
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Commercial product with platform-specific concepts.&lt;/li&gt;
&lt;li&gt;More complex than simple CI tools for small projects.&lt;/li&gt;
&lt;li&gt;Best value appears in larger organizations.&lt;/li&gt;
&lt;li&gt;Requires setup of connectors, delegates, projects, and organizations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real-World Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Enterprise continuous delivery with approvals.&lt;/li&gt;
&lt;li&gt;Deployments to Kubernetes and cloud environments.&lt;/li&gt;
&lt;li&gt;Standardized pipelines across many teams.&lt;/li&gt;
&lt;li&gt;Release governance with audit requirements.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;pipeline&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Testing Management Tools Comparison&lt;/span&gt;
  &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;testing_management_tools_comparison&lt;/span&gt;
  &lt;span class="na"&gt;stages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Unit Tests&lt;/span&gt;
        &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unit_tests&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;
        &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;cloneCodebase&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
          &lt;span class="na"&gt;platform&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;os&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Linux&lt;/span&gt;
            &lt;span class="na"&gt;arch&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Amd64&lt;/span&gt;
          &lt;span class="na"&gt;runtime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Cloud&lt;/span&gt;
            &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{}&lt;/span&gt;
          &lt;span class="na"&gt;execution&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;step&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run&lt;/span&gt;
                  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Python unit tests&lt;/span&gt;
                  &lt;span class="na"&gt;identifier&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;run_python_unit_tests&lt;/span&gt;
                  &lt;span class="na"&gt;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                    &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Sh&lt;/span&gt;
                    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
                      &lt;span class="s"&gt;cd sample-app&lt;/span&gt;
                      &lt;span class="s"&gt;PYTHONPATH=src python -m unittest discover -s tests&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repository includes this reference example in &lt;code&gt;harness/pipeline.yaml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;The best testing management tool depends on the development context. GitHub Actions is the most direct option for this repository because the code is hosted on GitHub. GitLab CI/CD is excellent when the full GitLab platform is used. Jenkins remains a strong choice when a team needs extreme customization or must integrate legacy systems. CircleCI, Travis CI, and Bitbucket Pipelines are easier hosted options with different ecosystem strengths. TeamCity provides enterprise build management and a typed configuration model. Tekton is the strongest Kubernetes-native option for teams building internal platforms. Harness is most valuable where continuous delivery governance, approvals, and auditability are major requirements.&lt;/p&gt;

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

&lt;p&gt;Testing management tools are not only test runners. They define how a team controls quality, automates feedback, protects releases, and creates repeatable delivery processes. A university-level comparison must therefore consider technical syntax, platform model, scalability, ecosystem, cost, and organizational fit. This repository demonstrates those factors with a working sample application and realistic configuration files for each tool.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Actions workflow syntax: &lt;a href="https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax" rel="noopener noreferrer"&gt;https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-syntax&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitLab CI/CD YAML syntax reference: &lt;a href="https://docs.gitlab.com/ci/yaml/" rel="noopener noreferrer"&gt;https://docs.gitlab.com/ci/yaml/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Jenkins Pipeline syntax: &lt;a href="https://www.jenkins.io/doc/book/pipeline/syntax/" rel="noopener noreferrer"&gt;https://www.jenkins.io/doc/book/pipeline/syntax/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;CircleCI configuration reference: &lt;a href="https://circleci.com/docs/reference/configuration-reference/" rel="noopener noreferrer"&gt;https://circleci.com/docs/reference/configuration-reference/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;TeamCity Kotlin DSL documentation: &lt;a href="https://www.jetbrains.com/help/teamcity/kotlin-dsl.html" rel="noopener noreferrer"&gt;https://www.jetbrains.com/help/teamcity/kotlin-dsl.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Travis CI build customization: &lt;a href="https://docs.travis-ci.com/user/customizing-the-build/" rel="noopener noreferrer"&gt;https://docs.travis-ci.com/user/customizing-the-build/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Bitbucket Pipelines configuration reference: &lt;a href="https://support.atlassian.com/bitbucket-cloud/docs/bitbucket-pipelines-configuration-reference/" rel="noopener noreferrer"&gt;https://support.atlassian.com/bitbucket-cloud/docs/bitbucket-pipelines-configuration-reference/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tekton Pipelines documentation: &lt;a href="https://tekton.dev/docs/pipelines/pipelines/" rel="noopener noreferrer"&gt;https://tekton.dev/docs/pipelines/pipelines/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Harness pipeline YAML documentation: &lt;a href="https://developer.harness.io/docs/platform/pipelines/yaml/" rel="noopener noreferrer"&gt;https://developer.harness.io/docs/platform/pipelines/yaml/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>cicd</category>
      <category>testing</category>
      <category>github</category>
    </item>
    <item>
      <title>Applying Pytest and Requests for Real-World API Testing in a FastAPI Application</title>
      <dc:creator>Abel Fernando PACOMPIA ORTIZ</dc:creator>
      <pubDate>Sat, 27 Jun 2026 07:41:53 +0000</pubDate>
      <link>https://dev.to/abel_fernandopacompiaor/applying-pytest-and-requests-for-real-world-api-testing-in-a-fastapi-application-3oj9</link>
      <guid>https://dev.to/abel_fernandopacompiaor/applying-pytest-and-requests-for-real-world-api-testing-in-a-fastapi-application-3oj9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;API testing is an essential practice for validating backend applications before they are deployed. In this project, I built a small FastAPI application and tested its endpoints using Pytest and FastAPI TestClient. The goal is to show a practical and academic example of how automated API tests can improve reliability.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is API Testing?
&lt;/h2&gt;

&lt;p&gt;API testing verifies the behavior of application endpoints. Instead of checking visual elements, API tests send HTTP requests and validate status codes, response bodies, data formats, and error handling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why API Testing is Important
&lt;/h2&gt;

&lt;p&gt;Modern applications often depend on APIs to connect frontends, services, databases, and external systems. If an API endpoint fails, many parts of the system can be affected. Automated API tests help detect problems early and provide confidence when making changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  API Testing Frameworks Comparative
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Framework&lt;/th&gt;
&lt;th&gt;Language / Ecosystem&lt;/th&gt;
&lt;th&gt;Best use case&lt;/th&gt;
&lt;th&gt;Automation support&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pytest + Requests / TestClient&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;Developer-friendly automated API tests&lt;/td&gt;
&lt;td&gt;Excellent with CI/CD tools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Postman + Newman&lt;/td&gt;
&lt;td&gt;JavaScript / CLI ecosystem&lt;/td&gt;
&lt;td&gt;Manual and automated API collections&lt;/td&gt;
&lt;td&gt;Good for pipeline execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rest Assured&lt;/td&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;API testing in Java projects&lt;/td&gt;
&lt;td&gt;Strong with Maven, Gradle, and CI&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Karate DSL&lt;/td&gt;
&lt;td&gt;Java / DSL&lt;/td&gt;
&lt;td&gt;BDD-style API tests with readable scenarios&lt;/td&gt;
&lt;td&gt;Good CI/CD integration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why I Chose Pytest
&lt;/h2&gt;

&lt;p&gt;I chose Pytest because it is simple, readable, and widely used in Python projects. It allows developers to write test functions with plain assertions, and it integrates easily with FastAPI through TestClient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo API with FastAPI
&lt;/h2&gt;

&lt;p&gt;The demo API provides endpoints for a welcome message, health check, listing users, retrieving a user by id, and creating a new user in memory.&lt;/p&gt;

&lt;p&gt;Example from &lt;code&gt;app/main.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/users/{user_id}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response_model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_user_by_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Return one user by id or a clear 404 error.&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;

    &lt;span class="k"&gt;raise&lt;/span&gt; &lt;span class="nc"&gt;HTTPException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;status_code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HTTP_404_NOT_FOUND&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;detail&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;User with id &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; was not found.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Writing Real-World API Test Cases
&lt;/h2&gt;

&lt;p&gt;The test suite checks successful responses, response content, list structures, user lookup, error handling, and validation failures.&lt;/p&gt;

&lt;p&gt;Example from &lt;code&gt;tests/test_api.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_health_check_returns_ok&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="c1"&gt;# Validates that the health endpoint reports the API as available.
&lt;/span&gt;    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/health&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running the Tests Locally
&lt;/h2&gt;

&lt;p&gt;To install dependencies and run the tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-r&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;requirements.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;pytest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-v&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automating API Tests with GitHub Actions
&lt;/h2&gt;

&lt;p&gt;GitHub Actions can run the test suite automatically when code is pushed or when a pull request is opened.&lt;/p&gt;

&lt;p&gt;Example from &lt;code&gt;.github/workflows/api-tests.yml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API Tests with Pytest&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;main"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api-tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The project includes seven API tests that validate the main behavior of the demo application. These tests can be executed locally with Pytest and automatically in GitHub Actions.&lt;/p&gt;

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

&lt;p&gt;Pytest is a strong option for API testing in Python because it is readable, flexible, and easy to automate. Combined with FastAPI and GitHub Actions, it supports a simple but effective workflow for validating backend behavior before deployment.&lt;/p&gt;

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

&lt;p&gt;GitHub repository: &lt;a href="https://github.com/Abel-GG-777/api-testing-pytest-demo.git" rel="noopener noreferrer"&gt;https://github.com/Abel-GG-777/api-testing-pytest-demo.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>fastapi</category>
      <category>pytest</category>
    </item>
    <item>
      <title>Applying Checkov SAST to Detect Security Issues in Terraform Infrastructure as Code</title>
      <dc:creator>Abel Fernando PACOMPIA ORTIZ</dc:creator>
      <pubDate>Sat, 27 Jun 2026 05:47:57 +0000</pubDate>
      <link>https://dev.to/abel_fernandopacompiaor/applying-checkov-sast-to-detect-security-issues-in-terraform-infrastructure-as-code-14gp</link>
      <guid>https://dev.to/abel_fernandopacompiaor/applying-checkov-sast-to-detect-security-issues-in-terraform-infrastructure-as-code-14gp</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Security issues in cloud infrastructure often start as small configuration mistakes. A public network rule, a missing encryption setting, or an overly permissive policy can create serious risk when infrastructure is deployed.&lt;/p&gt;

&lt;p&gt;This demo project shows how to use Checkov as a Static Application Security Testing tool for Terraform Infrastructure as Code. The goal is academic and practical: detect insecure Terraform configuration before deploying anything to the cloud.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Infrastructure as Code?
&lt;/h2&gt;

&lt;p&gt;Infrastructure as Code, or IaC, is the practice of defining infrastructure using code. Instead of manually creating cloud resources through a web console, teams describe resources in files that can be versioned, reviewed, tested, and automated.&lt;/p&gt;

&lt;p&gt;Terraform is one of the most popular IaC tools. It allows teams to define providers, networks, storage, compute resources, permissions, and other infrastructure components using declarative configuration files.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is SAST for IaC?
&lt;/h2&gt;

&lt;p&gt;Static Application Security Testing normally means analyzing source code without running it. For IaC, the same idea applies to infrastructure definitions. A scanner can inspect Terraform files and identify risky patterns before the infrastructure is created.&lt;/p&gt;

&lt;p&gt;This is useful because security feedback arrives earlier in the development lifecycle. Developers and DevOps teams can fix misconfigurations before they become real cloud exposure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Checkov?
&lt;/h2&gt;

&lt;p&gt;Checkov is a static analysis tool designed for Infrastructure as Code. It supports Terraform and can detect issues such as public access, missing encryption, weak network rules, and insecure cloud service configuration.&lt;/p&gt;

&lt;p&gt;For this project, Checkov is a good fit because it is simple to run locally, easy to integrate into GitHub Actions, and focused on IaC security scanning.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vulnerable Terraform demo
&lt;/h2&gt;

&lt;p&gt;The vulnerable Terraform file defines an AWS provider, a security group, and an S3 bucket. The file is intentionally insecure for demonstration purposes only.&lt;/p&gt;

&lt;p&gt;One important issue is SSH exposed to the entire internet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Insecure SSH access from anywhere"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SSH open to &lt;code&gt;0.0.0.0/0&lt;/code&gt; is insecure because any public IP address can attempt to connect. This increases the attack surface and can expose servers to brute-force attacks, credential attacks, and unauthorized access attempts.&lt;/p&gt;

&lt;p&gt;The vulnerable version also includes fully open outbound traffic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;egress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Overly permissive outbound access"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"-1"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fully open egress is too permissive because it allows outbound traffic to any destination, using any protocol and port. In a real environment, this can make data exfiltration or unauthorized external communication easier.&lt;/p&gt;

&lt;p&gt;The S3 bucket is also basic and does not define extra protections such as public access blocking or explicit encryption:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"vulnerable_bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"checkov-sast-demo-vulnerable-bucket"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Running Checkov locally
&lt;/h2&gt;

&lt;p&gt;Checkov can be installed and executed with Python:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-m&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;pip&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;install&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;checkov&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;checkov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--framework&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--skip-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;venv&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;checkov&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--framework&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;terraform&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--skip-path&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;venv&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-o&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;cli&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;checkov-report.txt&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;-d .&lt;/code&gt; option tells Checkov to scan the current directory. The &lt;code&gt;-o cli&lt;/code&gt; option prints the report in command-line format, and the final command stores the output in a text report.&lt;/p&gt;

&lt;h2&gt;
  
  
  Explaining findings
&lt;/h2&gt;

&lt;p&gt;Checkov analyzes the Terraform files and compares them with security policies. In this demo, it should identify risky patterns such as public SSH exposure, missing S3 security controls, and overly permissive network configuration.&lt;/p&gt;

&lt;p&gt;These findings matter because infrastructure misconfigurations can become real vulnerabilities after deployment. Detecting them statically helps reduce risk before cloud resources exist.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secure Terraform version
&lt;/h2&gt;

&lt;p&gt;The secure Terraform version restricts SSH to a trusted example IP address:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;ingress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"SSH access from a trusted example IP"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;22&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"203.0.113.10/32"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;203.0.113.10/32&lt;/code&gt; address is documentation-only example IP space. In a real project, this should be replaced with an approved corporate VPN, bastion host, or administrative IP range.&lt;/p&gt;

&lt;p&gt;The secure file also restricts egress to HTTPS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;egress&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"HTTPS outbound access only"&lt;/span&gt;
  &lt;span class="nx"&gt;from_port&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;
  &lt;span class="nx"&gt;to_port&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;443&lt;/span&gt;
  &lt;span class="nx"&gt;protocol&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"tcp"&lt;/span&gt;
  &lt;span class="nx"&gt;cidr_blocks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For S3, the secure version enables public access blocking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_public_access_block"&lt;/span&gt; &lt;span class="s2"&gt;"secure_bucket_public_access"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secure_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;block_public_acls&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_policy&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;ignore_public_acls&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;restrict_public_buckets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Blocking public access helps prevent accidental exposure of data. This is especially important because S3 buckets are commonly used to store sensitive application, backup, log, or user data.&lt;/p&gt;

&lt;p&gt;The secure version also enables server-side encryption:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_server_side_encryption_configuration"&lt;/span&gt; &lt;span class="s2"&gt;"secure_bucket_encryption"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;secure_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;apply_server_side_encryption_by_default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;sse_algorithm&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AES256"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;S3 encryption is a good practice because it protects stored objects at rest. Even when access controls are also required, encryption adds another layer of defense.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions automation
&lt;/h2&gt;

&lt;p&gt;The project includes a GitHub Actions workflow that runs Checkov automatically on pushes and pull requests to the &lt;code&gt;main&lt;/code&gt; branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkov IaC SAST Scan&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;checkov&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Checkov&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout repository&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Run Checkov Terraform scan&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bridgecrewio/checkov-action@master&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
          &lt;span class="na"&gt;framework&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;terraform&lt;/span&gt;
          &lt;span class="na"&gt;output_format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cli&lt;/span&gt;
          &lt;span class="na"&gt;soft_fail&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Integrating Checkov into GitHub Actions improves the DevSecOps workflow because every change can be scanned automatically before it is merged. This helps teams detect insecure Terraform code during code review instead of after deployment.&lt;/p&gt;

&lt;p&gt;In this academic demo, &lt;code&gt;soft_fail: true&lt;/code&gt; is used because the repository intentionally contains vulnerable Terraform code. This setting keeps the pipeline successful while still displaying the security findings in the workflow logs.&lt;/p&gt;

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

&lt;p&gt;This project demonstrates how Checkov can be used to detect security issues in Terraform Infrastructure as Code. The vulnerable version shows common cloud misconfigurations, while the secure version demonstrates safer alternatives.&lt;/p&gt;

&lt;p&gt;By combining local scanning with GitHub Actions automation, teams can introduce security checks early and continuously in the CI/CD process.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub repository link placeholder
&lt;/h2&gt;

&lt;p&gt;GitHub repository: &lt;a href="https://github.com/Abel-GG-777/checkov-terraform-sast-demo.git" rel="noopener noreferrer"&gt;https://github.com/Abel-GG-777/checkov-terraform-sast-demo.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>security</category>
      <category>devsecops</category>
      <category>checkov</category>
    </item>
    <item>
      <title>Applying Bandit SAST to Detect Vulnerabilities in a Python Flask Application</title>
      <dc:creator>Abel Fernando PACOMPIA ORTIZ</dc:creator>
      <pubDate>Sat, 27 Jun 2026 03:26:12 +0000</pubDate>
      <link>https://dev.to/abel_fernandopacompiaor/applying-bandit-sast-to-detect-vulnerabilities-in-a-python-flask-application-5g89</link>
      <guid>https://dev.to/abel_fernandopacompiaor/applying-bandit-sast-to-detect-vulnerabilities-in-a-python-flask-application-5g89</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Security should be part of the development workflow, not only a final checklist before deployment. One practical way to introduce security earlier is by using Static Application Security Testing tools. In this article, I demonstrate how to use Bandit to analyze a small Python Flask application that intentionally contains insecure code.&lt;/p&gt;

&lt;p&gt;GitHub repository: &lt;a href="https://github.com/Abel-GG-777/bandit-sast-python-demo" rel="noopener noreferrer"&gt;https://github.com/Abel-GG-777/bandit-sast-python-demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is SAST?
&lt;/h2&gt;

&lt;p&gt;Static Application Security Testing, commonly called SAST, is a security testing approach that analyzes source code without executing the application. Instead of waiting until runtime, SAST tools inspect code patterns and identify potential vulnerabilities early in the development lifecycle.&lt;/p&gt;

&lt;p&gt;SAST is especially useful in academic and professional environments because it can be automated in CI/CD pipelines and used by developers before code is merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Bandit?
&lt;/h2&gt;

&lt;p&gt;Bandit is a SAST tool designed specifically for Python. It scans Python files and reports common security issues such as hardcoded credentials, unsafe subprocess usage, weak cryptography, and risky configuration.&lt;/p&gt;

&lt;p&gt;For this demo, Bandit is a good choice because it is lightweight, easy to install, simple to run from the command line, and easy to integrate with GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo Vulnerable Code Explanation
&lt;/h2&gt;

&lt;p&gt;The demo application is a small Flask project in &lt;code&gt;app.py&lt;/code&gt;. It intentionally includes several insecure patterns so Bandit can detect them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A hardcoded administrator password stored directly in the source code.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;subprocess.check_output&lt;/code&gt; call using &lt;code&gt;shell=True&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;User input from a query parameter concatenated into a shell command, creating a possible command injection risk.&lt;/li&gt;
&lt;li&gt;The use of &lt;code&gt;hashlib.md5&lt;/code&gt;, a weak hashing algorithm for security-sensitive use cases.&lt;/li&gt;
&lt;li&gt;Flask running with &lt;code&gt;debug=True&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These vulnerabilities are intentionally simple so the results are easy to explain in a classroom or presentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Bandit Locally
&lt;/h2&gt;

&lt;p&gt;First, install the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run Bandit against the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; bandit &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To generate a text report, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; bandit &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; txt &lt;span class="nt"&gt;-o&lt;/span&gt; bandit-report.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explaining Findings
&lt;/h2&gt;

&lt;p&gt;Bandit reports issues with identifiers, severity levels, confidence levels, file paths, and line numbers. In this project, the expected findings are related to hardcoded credentials, subprocess execution, shell usage, MD5 hashing, and debug mode.&lt;/p&gt;

&lt;p&gt;The important part of the demo is not only seeing the warnings, but understanding why each pattern is risky. For example, &lt;code&gt;shell=True&lt;/code&gt; becomes dangerous when combined with user-controlled input because the shell may interpret special characters as commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secure Code Improvements
&lt;/h2&gt;

&lt;p&gt;The corrected version is implemented in &lt;code&gt;app_secure.py&lt;/code&gt;. It applies simple improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The password is loaded from the &lt;code&gt;ADMIN_PASSWORD&lt;/code&gt; environment variable.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shell=True&lt;/code&gt; is removed.&lt;/li&gt;
&lt;li&gt;The subprocess call uses a list of arguments instead of a shell command string.&lt;/li&gt;
&lt;li&gt;MD5 is replaced with SHA-256.&lt;/li&gt;
&lt;li&gt;Flask debug mode is disabled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This secure version keeps the application easy to understand while showing how vulnerable patterns can be improved.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions Automation
&lt;/h2&gt;

&lt;p&gt;The repository includes a GitHub Actions workflow at &lt;code&gt;.github/workflows/bandit.yml&lt;/code&gt;. It runs on pushes and pull requests targeting the &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;The workflow checks out the repository, configures Python 3.11, installs dependencies, and runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; bandit &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates how SAST can become part of a continuous integration process. Every push or pull request can be scanned automatically before changes are accepted.&lt;/p&gt;

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

&lt;p&gt;Bandit is a practical tool for introducing SAST into Python projects. It is simple to run locally, easy to automate, and useful for identifying common insecure coding patterns. This demo shows how a vulnerable Flask application can be scanned, how the findings can be explained, and how a corrected version can reduce the reported risks.&lt;/p&gt;

</description>
      <category>python</category>
      <category>flask</category>
      <category>security</category>
      <category>bandit</category>
    </item>
    <item>
      <title>Applying Bandit SAST to Detect Vulnerabilities in a Python Flask Application</title>
      <dc:creator>Abel Fernando PACOMPIA ORTIZ</dc:creator>
      <pubDate>Sat, 27 Jun 2026 03:26:12 +0000</pubDate>
      <link>https://dev.to/abel_fernandopacompiaor/applying-bandit-sast-to-detect-vulnerabilities-in-a-python-flask-application-542d</link>
      <guid>https://dev.to/abel_fernandopacompiaor/applying-bandit-sast-to-detect-vulnerabilities-in-a-python-flask-application-542d</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Security should be part of the development workflow, not only a final checklist before deployment. One practical way to introduce security earlier is by using Static Application Security Testing tools. In this article, I demonstrate how to use Bandit to analyze a small Python Flask application that intentionally contains insecure code.&lt;/p&gt;

&lt;p&gt;GitHub repository: &lt;a href="https://github.com/Abel-GG-777/bandit-sast-python-demo" rel="noopener noreferrer"&gt;https://github.com/Abel-GG-777/bandit-sast-python-demo&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What Is SAST?
&lt;/h2&gt;

&lt;p&gt;Static Application Security Testing, commonly called SAST, is a security testing approach that analyzes source code without executing the application. Instead of waiting until runtime, SAST tools inspect code patterns and identify potential vulnerabilities early in the development lifecycle.&lt;/p&gt;

&lt;p&gt;SAST is especially useful in academic and professional environments because it can be automated in CI/CD pipelines and used by developers before code is merged.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Bandit?
&lt;/h2&gt;

&lt;p&gt;Bandit is a SAST tool designed specifically for Python. It scans Python files and reports common security issues such as hardcoded credentials, unsafe subprocess usage, weak cryptography, and risky configuration.&lt;/p&gt;

&lt;p&gt;For this demo, Bandit is a good choice because it is lightweight, easy to install, simple to run from the command line, and easy to integrate with GitHub Actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo Vulnerable Code Explanation
&lt;/h2&gt;

&lt;p&gt;The demo application is a small Flask project in &lt;code&gt;app.py&lt;/code&gt;. It intentionally includes several insecure patterns so Bandit can detect them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A hardcoded administrator password stored directly in the source code.&lt;/li&gt;
&lt;li&gt;A &lt;code&gt;subprocess.check_output&lt;/code&gt; call using &lt;code&gt;shell=True&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;User input from a query parameter concatenated into a shell command, creating a possible command injection risk.&lt;/li&gt;
&lt;li&gt;The use of &lt;code&gt;hashlib.md5&lt;/code&gt;, a weak hashing algorithm for security-sensitive use cases.&lt;/li&gt;
&lt;li&gt;Flask running with &lt;code&gt;debug=True&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These vulnerabilities are intentionally simple so the results are easy to explain in a classroom or presentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running Bandit Locally
&lt;/h2&gt;

&lt;p&gt;First, install the dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run Bandit against the repository:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; bandit &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To generate a text report, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; bandit &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; txt &lt;span class="nt"&gt;-o&lt;/span&gt; bandit-report.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Explaining Findings
&lt;/h2&gt;

&lt;p&gt;Bandit reports issues with identifiers, severity levels, confidence levels, file paths, and line numbers. In this project, the expected findings are related to hardcoded credentials, subprocess execution, shell usage, MD5 hashing, and debug mode.&lt;/p&gt;

&lt;p&gt;The important part of the demo is not only seeing the warnings, but understanding why each pattern is risky. For example, &lt;code&gt;shell=True&lt;/code&gt; becomes dangerous when combined with user-controlled input because the shell may interpret special characters as commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Secure Code Improvements
&lt;/h2&gt;

&lt;p&gt;The corrected version is implemented in &lt;code&gt;app_secure.py&lt;/code&gt;. It applies simple improvements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The password is loaded from the &lt;code&gt;ADMIN_PASSWORD&lt;/code&gt; environment variable.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;shell=True&lt;/code&gt; is removed.&lt;/li&gt;
&lt;li&gt;The subprocess call uses a list of arguments instead of a shell command string.&lt;/li&gt;
&lt;li&gt;MD5 is replaced with SHA-256.&lt;/li&gt;
&lt;li&gt;Flask debug mode is disabled.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This secure version keeps the application easy to understand while showing how vulnerable patterns can be improved.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub Actions Automation
&lt;/h2&gt;

&lt;p&gt;The repository includes a GitHub Actions workflow at &lt;code&gt;.github/workflows/bandit.yml&lt;/code&gt;. It runs on pushes and pull requests targeting the &lt;code&gt;main&lt;/code&gt; branch.&lt;/p&gt;

&lt;p&gt;The workflow checks out the repository, configures Python 3.11, installs dependencies, and runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; bandit &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This demonstrates how SAST can become part of a continuous integration process. Every push or pull request can be scanned automatically before changes are accepted.&lt;/p&gt;

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

&lt;p&gt;Bandit is a practical tool for introducing SAST into Python projects. It is simple to run locally, easy to automate, and useful for identifying common insecure coding patterns. This demo shows how a vulnerable Flask application can be scanned, how the findings can be explained, and how a corrected version can reduce the reported risks.&lt;/p&gt;

</description>
      <category>python</category>
      <category>flask</category>
      <category>security</category>
      <category>bandit</category>
    </item>
  </channel>
</rss>
