<?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: karllui</title>
    <description>The latest articles on DEV Community by karllui (@karllui).</description>
    <link>https://dev.to/karllui</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3906495%2F32b47a40-a9e3-496c-bf65-a709b947aa28.png</url>
      <title>DEV Community: karllui</title>
      <link>https://dev.to/karllui</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/karllui"/>
    <language>en</language>
    <item>
      <title>Putting AI-Generated Blocks Into Your Working System 3</title>
      <dc:creator>karllui</dc:creator>
      <pubDate>Wed, 13 May 2026 16:48:51 +0000</pubDate>
      <link>https://dev.to/karllui/putting-ai-generated-blocks-into-your-working-system-3-2884</link>
      <guid>https://dev.to/karllui/putting-ai-generated-blocks-into-your-working-system-3-2884</guid>
      <description>&lt;p&gt;Part 3: Building a Complete URL Shortener &lt;/p&gt;

&lt;p&gt;In Part 1, we saw the problem: vibe coding collapses under its own weight. &lt;/p&gt;

&lt;p&gt;In Part 2, we introduced the methodology: Functional Block Design — Decomposition, Block Specs, Generation, Integration. &lt;/p&gt;

&lt;p&gt;Now we put it all together. &lt;/p&gt;

&lt;p&gt;This part contains the complete, runnable URL shortener built with FBD. Every block is here. Every .py file is complete. You can copy these files, run them, and see a working system. &lt;/p&gt;

&lt;p&gt;By the end of this post, you will have everything you need to try FBD on your own project. &lt;/p&gt;

&lt;p&gt;3.1 The Complete File Structure &lt;/p&gt;

&lt;p&gt;Here is every file in the project: &lt;/p&gt;

&lt;p&gt;text &lt;br&gt;
project/ &lt;br&gt;
├── url_validator.py      # Complete &lt;br&gt;
├── key_generator.py      # Complete &lt;br&gt;
├── storage_manager.py    # Complete &lt;br&gt;
├── redirect_handler.py   # Complete &lt;br&gt;
├── analytics_recorder.py # Complete &lt;br&gt;
├── api_router.py         # Complete &lt;br&gt;
└── main.py               # Integration - Run this &lt;br&gt;
Every block follows the same pattern: &lt;/p&gt;

&lt;p&gt;Header with Description (for humans) and Prompt (for AI) &lt;br&gt;
Generated code below the header &lt;br&gt;
One public function per block &lt;br&gt;
3.2 All Six Blocks (Complete) &lt;/p&gt;

&lt;p&gt;Here is every .py file in the project. You can copy them exactly as shown. &lt;/p&gt;

&lt;p&gt;url_validator.py &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block validates a raw URL string and returns a normalized version.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  It handles missing protocols, invalid characters, and malformed domains.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python function for a URL Validator block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Function signature:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def validate_url(raw_url: str) -&amp;gt; str:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  raw_url: a string, possibly missing protocol or malformed
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  validated_url: a normalized URL string with https:// prefix if missing
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Error handling:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If raw_url is empty, raise ValueError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If URL format is invalid, raise ValueError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. Add https:// prefix if no protocol is present.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. Use urlparse from urllib.parse for validation.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  3. Only accept http and https protocols.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Strip whitespace from input.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Return the normalized URL.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include docstring and type hints.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  url = validate_url("example.com")  # returns "&lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt;"
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;from urllib.parse import urlparse &lt;/p&gt;

&lt;p&gt;def validate_url(raw_url: str) -&amp;gt; str: &lt;br&gt;
    """Validate and normalize a URL string. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    raw_url: A URL string, possibly missing protocol. 

Returns: 
    A normalized URL string with https:// prefix. 

Raises: 
    ValueError: If raw_url is empty or invalid. 
""" 
if not raw_url: 
    raise ValueError("URL cannot be empty") 

raw_url = raw_url.strip() 

# Add https:// if no protocol is present 
if not urlparse(raw_url).scheme: 
    raw_url = "https://" + raw_url 

parsed = urlparse(raw_url) 

if parsed.scheme not in ("http", "https"): 
    raise ValueError(f"Invalid protocol: {parsed.scheme}. Only http and https are allowed.") 

if not parsed.netloc: 
    raise ValueError(f"Invalid URL: missing domain. {raw_url}") 

return raw_url 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;key_generator.py &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block generates a unique 6-8 character alphanumeric key for a given URL.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  It handles key collisions by retrying up to 10 times.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python function for a Key Generator block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Function signature:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def generate_key(original_url: str) -&amp;gt; str:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  original_url: a string, already validated
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key: a string, 6 to 8 alphanumeric characters (digits 0-9, uppercase A-Z, lowercase a-z)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Error handling:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If original_url is empty, raise ValueError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If unable to generate a unique key after 10 attempts, raise RuntimeError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. The key must be unique. No two URLs get the same key.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. Use base62 encoding (digits + uppercase + lowercase).
&lt;/h1&gt;

&lt;h1&gt;
  
  
  3. Before returning a key, check if it already exists by calling
&lt;/h1&gt;

&lt;h1&gt;
  
  
  storage_key_exists(key). This helper will be provided by the Storage Manager block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  4. If collision happens, generate a new key and try again.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  5. Keep trying until you find a unique key or you have attempted 10 times.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Use the random module to generate candidate keys
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include a docstring and type hints
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Keep the function pure (no side effects beyond storage_key_exists)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key = generate_key("&lt;a href="https://example.com%22" rel="noopener noreferrer"&gt;https://example.com"&lt;/a&gt;)  # returns "aB3xY9"
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;import random &lt;br&gt;
import string &lt;/p&gt;

&lt;h1&gt;
  
  
  This will be imported from storage_manager at runtime
&lt;/h1&gt;

&lt;h1&gt;
  
  
  For standalone testing, you can mock it
&lt;/h1&gt;

&lt;p&gt;def storage_key_exists(key: str) -&amp;gt; bool: &lt;br&gt;
    """Mock function - will be replaced by actual storage_manager.""" &lt;br&gt;
    # This is a placeholder. The real storage_manager will provide this. &lt;br&gt;
    return False &lt;/p&gt;

&lt;p&gt;def generate_key(original_url: str) -&amp;gt; str: &lt;br&gt;
    """Generate a unique 6-8 character alphanumeric key for a given URL. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    original_url: A validated URL string. 

Returns: 
    A unique 6-8 character alphanumeric key. 

Raises: 
    ValueError: If original_url is empty. 
    RuntimeError: If unable to generate a unique key after 10 attempts. 
""" 
if not original_url: 
    raise ValueError("URL cannot be empty") 

chars = string.digits + string.ascii_letters 

for attempt in range(10): 
    length = random.randint(6, 8) 
    key = ''.join(random.choices(chars, k=length)) 

    if not storage_key_exists(key): 
        return key 

raise RuntimeError("Failed to generate unique key after 10 attempts") 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;storage_manager.py &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block stores (key, URL) pairs in an in-memory dictionary
&lt;/h1&gt;

&lt;h1&gt;
  
  
  and retrieves URLs by key. For production, replace with a database.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python module for a Storage Manager block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Functions:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def save_url(key: str, url: str) -&amp;gt; None:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def get_url(key: str) -&amp;gt; str | None:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def key_exists(key: str) -&amp;gt; bool:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key: a string key
&lt;/h1&gt;

&lt;h1&gt;
  
  
  url: a string URL
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  save_url: None
&lt;/h1&gt;

&lt;h1&gt;
  
  
  get_url: URL string or None if not found
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key_exists: True if key exists, False otherwise
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Error handling:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If key or url is empty, raise ValueError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. Use an in-memory dictionary for storage.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. Thread-safe is not required for this example.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  3. key_exists is used by key_generator to check collisions.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Keep the dictionary as a module-level variable.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include docstrings and type hints.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  save_url("abc123", "&lt;a href="https://example.com%22" rel="noopener noreferrer"&gt;https://example.com"&lt;/a&gt;)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  url = get_url("abc123")  # returns "&lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt;"
&lt;/h1&gt;

&lt;h1&gt;
  
  
  exists = key_exists("abc123")  # returns True
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;_store: dict[str, str] = {} &lt;/p&gt;

&lt;p&gt;def save_url(key: str, url: str) -&amp;gt; None: &lt;br&gt;
    """Store a (key, URL) pair. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    key: The short key. 
    url: The original URL. 

Raises: 
    ValueError: If key or url is empty. 
""" 
if not key: 
    raise ValueError("Key cannot be empty") 
if not url: 
    raise ValueError("URL cannot be empty") 
_store[key] = url 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;def get_url(key: str) -&amp;gt; str | None: &lt;br&gt;
    """Retrieve a URL by its key. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    key: The short key. 

Returns: 
    The original URL if found, None otherwise. 
""" 
return _store.get(key) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;def key_exists(key: str) -&amp;gt; bool: &lt;br&gt;
    """Check if a key already exists. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    key: The short key. 

Returns: 
    True if the key exists, False otherwise. 
""" 
return key in _store 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;redirect_handler.py &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block accepts a short key and returns an HTTP redirect response
&lt;/h1&gt;

&lt;h1&gt;
  
  
  or a 404 response if the key is not found.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python function for a Redirect Handler block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Function signature:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def create_redirect_response(original_url: str) -&amp;gt; tuple[str, int]:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  original_url: a string, the original long URL
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  A tuple of (message, status_code)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - On success: (redirect_url, 302)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - On not found: ("Not found", 404)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. Return a 302 Found redirect response.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. If original_url is None or empty, return 404.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - This is a simplified response. In a real web framework,
&lt;/h1&gt;

&lt;h1&gt;
  
  
  you would return a proper Response object.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include docstring and type hints.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  response = create_redirect_response("&lt;a href="https://example.com%22" rel="noopener noreferrer"&gt;https://example.com"&lt;/a&gt;)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  # returns ("&lt;a href="https://example.com" rel="noopener noreferrer"&gt;https://example.com&lt;/a&gt;", 302)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;def create_redirect_response(original_url: str | None) -&amp;gt; tuple[str, int]: &lt;br&gt;
    """Create an HTTP redirect or 404 response. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    original_url: The original long URL, or None if not found. 

Returns: 
    A tuple of (message, status_code). 
    - (redirect_url, 302) for a redirect 
    - ("Not found", 404) for a missing key 
""" 
if not original_url: 
    return "Not found", 404 
return original_url, 302 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;analytics_recorder.py &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block records click events (timestamp, key, referrer, IP)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  for analytics purposes. For production, write to a database.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python function for an Analytics Recorder block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Function signature:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def record_click(key: str, request_context: dict) -&amp;gt; None:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key: a string, the short key that was clicked
&lt;/h1&gt;

&lt;h1&gt;
  
  
  request_context: a dict containing at least "ip" and "referrer"
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  None
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. Record the click with timestamp, key, IP, and referrer.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. For this example, print to console (production would use a database).
&lt;/h1&gt;

&lt;h1&gt;
  
  
  3. Do not raise exceptions for analytics failures (non-blocking).
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Use datetime.now() for timestamp.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include docstring and type hints.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Use try/except to prevent analytics failures from breaking the redirect.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  context = {"ip": "192.168.1.1", "referrer": "&lt;a href="https://google.com%22" rel="noopener noreferrer"&gt;https://google.com"&lt;/a&gt;}
&lt;/h1&gt;

&lt;h1&gt;
  
  
  record_click("abc123", context)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;from datetime import datetime &lt;br&gt;
from typing import Any &lt;/p&gt;

&lt;p&gt;def record_click(key: str, request_context: dict[str, Any]) -&amp;gt; None: &lt;br&gt;
    """Record a click event for analytics. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    key: The short key that was clicked. 
    request_context: Dictionary containing 'ip' and 'referrer'. 
""" 
try: 
    timestamp = datetime.now().isoformat() 
    ip = request_context.get("ip", "unknown") 
    referrer = request_context.get("referrer", "unknown") 

    # In production, write to a database or message queue 
    print(f"[ANALYTICS] {timestamp} | key={key} | ip={ip} | referrer={referrer}") 
except Exception as e: 
    # Non-blocking: analytics failure should not break the redirect 
    print(f"[ANALYTICS ERROR] Failed to record click: {e}") 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;api_router.py &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block routes HTTP requests to the appropriate handler.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  It maps POST /shorten to create handler and GET /{key} to redirect handler.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python function for an API Router block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Function signature:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def route_request(routes: dict) -&amp;gt; object:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  routes: a dict mapping path patterns to handler functions
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  An app object (simplified for this example)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. This is a simplified router for demonstration.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. In production, use FastAPI, Flask, or similar.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  3. The returned app has a run() method.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - This is a mock router to keep the example self-contained.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include docstring and type hints.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  app = route_request({
&lt;/h1&gt;

&lt;h1&gt;
  
  
  "POST /shorten": handle_create,
&lt;/h1&gt;

&lt;h1&gt;
  
  
  "GET /{key}": handle_redirect
&lt;/h1&gt;

&lt;h1&gt;
  
  
  })
&lt;/h1&gt;

&lt;h1&gt;
  
  
  app.run()
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;from typing import Callable &lt;/p&gt;

&lt;p&gt;class SimpleApp: &lt;br&gt;
    """A mock web app for demonstration purposes.""" &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;def __init__(self, routes: dict[str, Callable]): 
    self.routes = routes 

def run(self): 
    """Run the mock app.""" 
    print("\n" + "=" * 50) 
    print("URL Shortener is ready!") 
    print("=" * 50) 
    print("\nThis is a mock router for demonstration.") 
    print("In production, replace with FastAPI, Flask, etc.") 
    print("\nAvailable routes:") 
    for path, handler in self.routes.items(): 
        print(f"  {path} -&amp;gt; {handler.__name__}") 
    print("\nExample curl commands:") 
    print('  curl -X POST http://localhost:8000/shorten -H "Content-Type: application/json" -d \'{"url": "https://example.com"}\'') 
    print("  curl http://localhost:8000/abc123") 
    print("\n" + "=" * 50) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;def route_request(routes: dict[str, Callable]) -&amp;gt; SimpleApp: &lt;br&gt;
    """Create a mock app with the given routes. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    routes: A dictionary mapping path patterns to handler functions. 

Returns: 
    A SimpleApp object with a run() method. 
""" 
return SimpleApp(routes) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;3.3 The Integration (main.py) &lt;/p&gt;

&lt;p&gt;Here is main.py — the file that connects everything and runs the system. &lt;/p&gt;

&lt;h1&gt;
  
  
  main.py - Integration harness for URL Shortener
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This file connects all functional blocks into a working system.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  It defines the data flow and handles errors across block boundaries.
&lt;/h1&gt;

&lt;p&gt;from url_validator import validate_url &lt;br&gt;
from key_generator import generate_key &lt;br&gt;
from storage_manager import save_url, get_url, key_exists &lt;br&gt;
from redirect_handler import create_redirect_response &lt;br&gt;
from analytics_recorder import record_click &lt;br&gt;
from api_router import route_request &lt;/p&gt;

&lt;h1&gt;
  
  
  Override key_exists in key_generator to use storage_manager
&lt;/h1&gt;

&lt;p&gt;import key_generator &lt;br&gt;
key_generator.storage_key_exists = key_exists &lt;/p&gt;

&lt;p&gt;def handle_create_url(raw_url: str): &lt;br&gt;
    """Full pipeline: validate -&amp;gt; generate key -&amp;gt; store -&amp;gt; return short URL""" &lt;br&gt;
    try: &lt;br&gt;
        validated_url = validate_url(raw_url) &lt;br&gt;
        key = generate_key(validated_url) &lt;br&gt;
        save_url(key, validated_url) &lt;br&gt;
        return f"&lt;a href="https://short.url/%7Bkey%7D" rel="noopener noreferrer"&gt;https://short.url/{key}&lt;/a&gt;", 200 &lt;br&gt;
    except ValueError as e: &lt;br&gt;
        return f"Invalid URL: {e}", 400 &lt;br&gt;
    except RuntimeError as e: &lt;br&gt;
        return f"Failed to generate unique key: {e}", 500 &lt;/p&gt;

&lt;p&gt;def handle_redirect(key: str, request_context: dict): &lt;br&gt;
    """Full pipeline: lookup -&amp;gt; record analytics -&amp;gt; redirect""" &lt;br&gt;
    original_url = get_url(key) &lt;br&gt;
    if not original_url: &lt;br&gt;
        return "Not found", 404 &lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Non-blocking analytics: log and continue &lt;br&gt;
record_click(key, request_context) 

&lt;p&gt;return create_redirect_response(original_url) &lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  The API router calls these functions based on request type&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;app = route_request({ &lt;br&gt;
    "POST /shorten": handle_create_url, &lt;br&gt;
    "GET /{key}": handle_redirect &lt;br&gt;
}) &lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;": &lt;br&gt;
    app.run() &lt;/p&gt;

&lt;p&gt;3.4 How to Run It &lt;/p&gt;

&lt;p&gt;Save all 7 files in the same directory. &lt;br&gt;
Make sure you have Python 3.8 or later installed. &lt;br&gt;
Run python main.py &lt;br&gt;
You will see: &lt;/p&gt;

&lt;p&gt;================================================== &lt;/p&gt;

&lt;h1&gt;
  
  
  URL Shortener is ready! 
&lt;/h1&gt;

&lt;p&gt;This is a mock router for demonstration. &lt;br&gt;
In production, replace with FastAPI, Flask, etc. &lt;/p&gt;

&lt;p&gt;Available routes: &lt;br&gt;
  POST /shorten -&amp;gt; handle_create_url &lt;br&gt;
  GET /{key} -&amp;gt; handle_redirect &lt;/p&gt;

&lt;p&gt;Example curl commands: &lt;br&gt;
  curl -X POST &lt;a href="http://localhost:8000/shorten" rel="noopener noreferrer"&gt;http://localhost:8000/shorten&lt;/a&gt; -H "Content-Type: application/json" -d '{"url": "&lt;a href="https://example.com%22%7D" rel="noopener noreferrer"&gt;https://example.com"}&lt;/a&gt;' &lt;br&gt;
  curl &lt;a href="http://localhost:8000/abc123" rel="noopener noreferrer"&gt;http://localhost:8000/abc123&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;================================================== &lt;/p&gt;

&lt;p&gt;The system is complete. Every block works. You can extend it with a real web framework, a database, and proper testing. &lt;/p&gt;

&lt;p&gt;3.5 What This Demonstrates &lt;/p&gt;

&lt;p&gt;What You Just Saw &lt;br&gt;
Why It Matters &lt;br&gt;
Six complete .py files &lt;br&gt;
Every block is here. No missing pieces. &lt;br&gt;
Clear interfaces &lt;br&gt;
Each block's inputs, outputs, and errors are explicit. &lt;br&gt;
Integration in one file &lt;br&gt;
main.py shows exactly how blocks connect. &lt;br&gt;
Reproducible &lt;br&gt;
Every block can be regenerated from its Prompt. &lt;br&gt;
Maintainable &lt;br&gt;
Change one block. The others keep working. &lt;br&gt;
Runnable &lt;br&gt;
You can copy and run it today. &lt;br&gt;
This is not a toy. It is a complete system built with FBD. &lt;/p&gt;

&lt;p&gt;3.6 What You Learned in This Series &lt;/p&gt;

&lt;p&gt;Part 1: The Problem &lt;/p&gt;

&lt;p&gt;Vibe coding collapses when projects grow. &lt;br&gt;
AI thinks in functions, not systems. &lt;br&gt;
The solution is not a better prompt. It is a different way to structure work. &lt;br&gt;
Part 2: The Methodology &lt;/p&gt;

&lt;p&gt;Decompose the system into functional blocks. &lt;br&gt;
Write a Block Spec (Description + Prompt) in each .py file header. &lt;br&gt;
Generate each block from its Prompt. &lt;br&gt;
Integrate the blocks in main.py. &lt;br&gt;
Part 3: Putting It All Together &lt;/p&gt;

&lt;p&gt;The complete, runnable URL shortener. &lt;br&gt;
Six blocks, one integration file, one working system. &lt;br&gt;
Clear, reproducible, maintainable. &lt;/p&gt;

&lt;p&gt;3.7 What You Should Do Next &lt;/p&gt;

&lt;p&gt;Try FBD on your own project this week. &lt;/p&gt;

&lt;p&gt;Start small. Pick a system with three or four blocks. Write the Description and Prompt carefully. Generate each block. Connect them. &lt;/p&gt;

&lt;p&gt;You will make mistakes. Your first Prompt may not produce perfect code. That is normal. Refine it. The Prompt lives in the file header. You can improve it over time. &lt;/p&gt;

&lt;p&gt;The investment pays off quickly: &lt;/p&gt;

&lt;p&gt;After This Many Projects &lt;br&gt;
You Will &lt;br&gt;
1 project &lt;br&gt;
Understand the rhythm of decomposition and integration &lt;br&gt;
3 projects &lt;br&gt;
Write better Prompts faster. Avoid common mistakes. &lt;br&gt;
5 projects &lt;br&gt;
Apply FBD without thinking. It becomes your default way to work with AI. &lt;br&gt;
3.8 A Final Thought &lt;/p&gt;

&lt;p&gt;The relationship between human and AI is still being figured out. &lt;/p&gt;

&lt;p&gt;Some people think AI will replace programmers. &lt;br&gt;
Some people think AI is just a toy. &lt;/p&gt;

&lt;p&gt;Both are wrong. &lt;/p&gt;

&lt;p&gt;The truth is more interesting: AI changes what programming means. &lt;/p&gt;

&lt;p&gt;The human becomes less of a coder and more of an architect — decomposing systems, writing specifications, validating integration. The AI becomes less of an assistant and more of a builder — generating correct, focused code from clear instructions. &lt;/p&gt;

&lt;p&gt;Functional Block Design is one way to make that relationship work. &lt;/p&gt;

&lt;p&gt;It is simple. It is practical. It is reproducible. &lt;/p&gt;

&lt;p&gt;And it works. &lt;/p&gt;

&lt;p&gt;3.9 Where to Go From Here &lt;/p&gt;

&lt;p&gt;Try it. Build something small. See for yourself. &lt;/p&gt;

&lt;p&gt;Share it. Tell others about FBD. Link to this series. Start a conversation. &lt;/p&gt;

&lt;p&gt;Improve it. FBD is not sacred. Adapt it to your workflow. Make it better. &lt;/p&gt;

&lt;p&gt;The code is yours. The methodology is yours. The system is yours. &lt;/p&gt;

&lt;p&gt;The End &lt;/p&gt;

&lt;p&gt;Thank you for reading this series. &lt;/p&gt;

&lt;p&gt;If you found it useful, share it with someone who struggles with AI-generated code. Write a blog post about your own experience with FBD. Or just go build something. &lt;/p&gt;

&lt;p&gt;Either way, you now have a complete, runnable example of a system built with Functional Block Design. &lt;/p&gt;

&lt;p&gt;Go put it to work. &lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>softwareengineering</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Putting AI-Generated Blocks Into Your Working System-2</title>
      <dc:creator>karllui</dc:creator>
      <pubDate>Sat, 09 May 2026 03:52:05 +0000</pubDate>
      <link>https://dev.to/karllui/putting-ai-generated-blocks-into-your-working-system-4pc5</link>
      <guid>https://dev.to/karllui/putting-ai-generated-blocks-into-your-working-system-4pc5</guid>
      <description>&lt;p&gt;Part 2: Functional Block Design — The Methodology &lt;/p&gt;

&lt;p&gt;In Part 1, we identified the problem: vibe coding collapses when projects grow beyond a handful of features. We discovered the core insight: AI thinks in functions, not systems. &lt;/p&gt;

&lt;p&gt;Now we need a methodology. &lt;/p&gt;

&lt;p&gt;This part introduces Functional Block Design (FBD) — a repeatable, four-phase process for building systems from AI-generated blocks. &lt;/p&gt;

&lt;p&gt;Phase 1: Decomposition — Break the system into functional blocks. &lt;br&gt;
Phase 2: Block Specs — Write a Description (for humans) and a Prompt (for AI) in each .py file header. &lt;br&gt;
Phase 3: Generation — Generate code from the Prompt. &lt;br&gt;
Phase 4: Integration — Connect the blocks into a working system. &lt;br&gt;
We use Python as the example language. One functional block = one .py file. Each .py file contains a header (Description + Prompt) and the generated code below. &lt;/p&gt;

&lt;p&gt;Let us walk through each phase using a URL shortener as our running example. &lt;/p&gt;

&lt;p&gt;2.1 Phase 1: Decomposition &lt;/p&gt;

&lt;p&gt;Goal: Break the system into functional blocks. Each block is a self-contained unit with a single, clear responsibility. In code, it becomes one function. &lt;/p&gt;

&lt;p&gt;Rule: Each block must be describable in one sentence. That sentence becomes the Description in the file header. &lt;/p&gt;

&lt;p&gt;Example: URL Shortener Decomposition &lt;/p&gt;

&lt;p&gt;Here is how we decompose a URL shortener into six functional blocks: &lt;/p&gt;

&lt;p&gt;Block &lt;br&gt;
Responsibility &lt;br&gt;
One Sentence Description &lt;br&gt;
URL Validator &lt;br&gt;
Validates a raw URL string and returns a normalized version or an error &lt;/p&gt;

&lt;p&gt;Key Generator &lt;br&gt;
Generates a unique 6-8 character alphanumeric key for a given URL &lt;/p&gt;

&lt;p&gt;Storage Manager &lt;br&gt;
Stores a (key, URL) pair in the database and retrieves URL by key &lt;/p&gt;

&lt;p&gt;Redirect Handler &lt;br&gt;
Accepts a short key and returns an HTTP redirect response (or 404) &lt;/p&gt;

&lt;p&gt;Analytics Recorder &lt;br&gt;
Records click events (timestamp, referrer, IP) for a given key &lt;/p&gt;

&lt;p&gt;API Router &lt;br&gt;
Routes HTTP requests to the appropriate handler (create, redirect, analytics) &lt;/p&gt;

&lt;p&gt;Why we stop here: &lt;/p&gt;

&lt;p&gt;We do not break the Key Generator into smaller blocks (e.g., "Generate Random String" and "Check Uniqueness") because the uniqueness check is integral to key generation. Splitting them would create coordination complexity that the AI handles better inside a single function. This is the functional integrity rule: a block should be a complete function, not an arbitrary fragment. &lt;/p&gt;

&lt;p&gt;2.2 Phase 2: Block Specs &lt;/p&gt;

&lt;p&gt;Goal: For each block, create a .py file with a header containing two sections: &lt;/p&gt;

&lt;p&gt;Section &lt;br&gt;
Audience &lt;br&gt;
Purpose &lt;br&gt;
Description &lt;br&gt;
Humans &lt;br&gt;
Simple English telling what this block does &lt;br&gt;
Prompt &lt;br&gt;
AI &lt;br&gt;
Detailed instructions for generating the code (signature, inputs, outputs, error handling, requirements, example) &lt;br&gt;
The Prompt must include: &lt;/p&gt;

&lt;p&gt;Function signature &lt;br&gt;
Inputs &lt;br&gt;
Outputs &lt;br&gt;
Error handling &lt;br&gt;
Requirements &lt;br&gt;
Implementation notes (optional) &lt;br&gt;
Example &lt;br&gt;
Example: Key Generator — Complete .py File Header &lt;/p&gt;

&lt;p&gt;Here is key_generator.py with the header only (code not yet generated): &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block generates a unique 6-8 character alphanumeric key for a given URL.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  It handles key collisions by retrying up to 10 times.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python function for a Key Generator block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Function signature:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def generate_key(original_url: str) -&amp;gt; str:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  original_url: a string, already validated
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key: a string, 6 to 8 alphanumeric characters (digits 0-9, uppercase A-Z, lowercase a-z)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Error handling:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If original_url is empty, raise ValueError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If unable to generate a unique key after 10 attempts, raise RuntimeError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. The key must be unique. No two URLs get the same key.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. Use base62 encoding (digits + uppercase + lowercase).
&lt;/h1&gt;

&lt;h1&gt;
  
  
  3. Before returning a key, check if it already exists by calling
&lt;/h1&gt;

&lt;h1&gt;
  
  
  storage_key_exists(key). This helper will be provided by the Storage Manager block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  4. If collision happens, generate a new key and try again.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  5. Keep trying until you find a unique key or you have attempted 10 times.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Use the random module to generate candidate keys
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include a docstring and type hints
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Keep the function pure (no side effects beyond storage_key_exists)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key = generate_key("&lt;a href="https://example.com%22" rel="noopener noreferrer"&gt;https://example.com"&lt;/a&gt;)  # returns "aB3xY9"
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;The Description is short and human-friendly. The Prompt is detailed and AI-ready. Both live in the same file. No duplication. No separate files. &lt;/p&gt;

&lt;p&gt;The other five blocks (URL Validator, Storage Manager, Redirect Handler, Analytics Recorder, API Router) are created the same way. Each has its own .py file with Description and Prompt. &lt;/p&gt;

&lt;p&gt;2.3 Phase 3: Generation &lt;/p&gt;

&lt;p&gt;Goal: Feed the Prompt to an AI and receive working code. Paste the generated code below the header. &lt;/p&gt;

&lt;p&gt;Process: &lt;/p&gt;

&lt;p&gt;Step &lt;br&gt;
Action &lt;br&gt;
1 &lt;br&gt;
Copy the Prompt section from the .py file &lt;br&gt;
2 &lt;br&gt;
Paste it into your AI tool (Claude, GPT, Copilot) &lt;br&gt;
3 &lt;br&gt;
AI generates the code &lt;br&gt;
4 &lt;br&gt;
Human reviews for errors (wrong signature, missing imports, incorrect logic) &lt;br&gt;
5 &lt;br&gt;
If incorrect, refine the Prompt and generate again &lt;br&gt;
6 &lt;br&gt;
Paste the generated code below the header &lt;br&gt;
7 &lt;br&gt;
Repeat for each block &lt;br&gt;
Important: Do not move to integration until each block passes its own minimal tests in isolation. &lt;/p&gt;

&lt;p&gt;Example: Complete key_generator.py (Header + Generated Code) &lt;/p&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  DESCRIPTION
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This block generates a unique 6-8 character alphanumeric key for a given URL.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  It handles key collisions by retrying up to 10 times.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  PROMPT
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Generate a Python function for a Key Generator block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Function signature:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  def generate_key(original_url: str) -&amp;gt; str:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Inputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  original_url: a string, already validated
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Outputs:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key: a string, 6 to 8 alphanumeric characters (digits 0-9, uppercase A-Z, lowercase a-z)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Error handling:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If original_url is empty, raise ValueError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - If unable to generate a unique key after 10 attempts, raise RuntimeError
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Requirements:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  1. The key must be unique. No two URLs get the same key.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  2. Use base62 encoding (digits + uppercase + lowercase).
&lt;/h1&gt;

&lt;h1&gt;
  
  
  3. Before returning a key, check if it already exists by calling
&lt;/h1&gt;

&lt;h1&gt;
  
  
  storage_key_exists(key). This helper will be provided by the Storage Manager block.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  4. If collision happens, generate a new key and try again.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  5. Keep trying until you find a unique key or you have attempted 10 times.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Implementation notes:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Use the random module to generate candidate keys
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Include a docstring and type hints
&lt;/h1&gt;

&lt;h1&gt;
  
  
  - Keep the function pure (no side effects beyond storage_key_exists)
&lt;/h1&gt;

&lt;h1&gt;
  
  
  Example:
&lt;/h1&gt;

&lt;h1&gt;
  
  
  key = generate_key("&lt;a href="https://example.com%22" rel="noopener noreferrer"&gt;https://example.com"&lt;/a&gt;)  # returns "aB3xY9"
&lt;/h1&gt;

&lt;h1&gt;
  
  
  ============================================================
&lt;/h1&gt;

&lt;p&gt;import random &lt;br&gt;
import string &lt;/p&gt;

&lt;p&gt;def generate_key(original_url: str) -&amp;gt; str: &lt;br&gt;
    """Generate a unique 6-8 character alphanumeric key for a given URL. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Args: 
    original_url: A validated URL string. 

Returns: 
    A unique 6-8 character alphanumeric key. 

Raises: 
    ValueError: If original_url is empty. 
    RuntimeError: If unable to generate a unique key after 10 attempts. 
""" 
if not original_url: 
    raise ValueError("URL cannot be empty") 

chars = string.digits + string.ascii_letters 

for attempt in range(10): 
    length = random.randint(6, 8) 
    key = ''.join(random.choices(chars, k=length)) 

    if not storage_key_exists(key): 
        return key 

raise RuntimeError("Failed to generate unique key after 10 attempts") 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The generated code follows the Prompt precisely. The function signature matches. Inputs, outputs, and error handling match. Requirements are satisfied. The code is runnable. &lt;/p&gt;

&lt;p&gt;We repeat this process for the remaining five blocks. Each gets its own .py file with header and generated code. &lt;/p&gt;

&lt;p&gt;2.4 Phase 4: Integration &lt;/p&gt;

&lt;p&gt;Goal: Connect the independently generated functions into a working system. &lt;/p&gt;

&lt;p&gt;Process: &lt;/p&gt;

&lt;p&gt;Step &lt;br&gt;
Action &lt;br&gt;
1 &lt;br&gt;
Define the data flow between blocks &lt;br&gt;
2 &lt;br&gt;
Write a main.py file that imports all blocks and calls them in order &lt;br&gt;
3 &lt;br&gt;
Handle errors and edge cases across block boundaries &lt;br&gt;
4 &lt;br&gt;
Add configuration, logging, and cross-cutting concerns &lt;br&gt;
5 &lt;br&gt;
Test the integrated system end to end &lt;br&gt;
Who does what: &lt;/p&gt;

&lt;p&gt;Role &lt;br&gt;
Responsibility &lt;br&gt;
Human &lt;br&gt;
Define orchestration order, validate that blocks work together, make judgment calls &lt;br&gt;
AI &lt;br&gt;
Generate boilerplate (main.py), write glue code, generate integration tests &lt;br&gt;
Example: main.py (Integration Harness) &lt;/p&gt;

&lt;h1&gt;
  
  
  main.py - Integration harness for URL Shortener
&lt;/h1&gt;

&lt;h1&gt;
  
  
  This file connects all functional blocks into a working system.
&lt;/h1&gt;

&lt;h1&gt;
  
  
  It defines the data flow and handles errors across block boundaries.
&lt;/h1&gt;

&lt;p&gt;from url_validator import validate_url &lt;br&gt;
from key_generator import generate_key &lt;br&gt;
from storage_manager import save_url, get_url &lt;br&gt;
from redirect_handler import create_redirect_response &lt;br&gt;
from analytics_recorder import record_click &lt;br&gt;
from api_router import route_request &lt;/p&gt;

&lt;p&gt;def handle_create_url(raw_url: str): &lt;br&gt;
    """Full pipeline: validate -&amp;gt; generate key -&amp;gt; store -&amp;gt; return short URL""" &lt;br&gt;
    try: &lt;br&gt;
        validated_url = validate_url(raw_url) &lt;br&gt;
        key = generate_key(validated_url) &lt;br&gt;
        save_url(key, validated_url) &lt;br&gt;
        return f"&lt;a href="https://short.url/%7Bkey%7D" rel="noopener noreferrer"&gt;https://short.url/{key}&lt;/a&gt;", 200 &lt;br&gt;
    except ValueError as e: &lt;br&gt;
        return f"Invalid URL: {e}", 400 &lt;br&gt;
    except RuntimeError as e: &lt;br&gt;
        return f"Failed to generate unique key: {e}", 500 &lt;/p&gt;

&lt;p&gt;def handle_redirect(key: str, request_context: dict): &lt;br&gt;
    """Full pipeline: lookup -&amp;gt; record analytics -&amp;gt; redirect""" &lt;br&gt;
    original_url = get_url(key) &lt;br&gt;
    if not original_url: &lt;br&gt;
        return "Not found", 404 &lt;/p&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Non-blocking analytics: log and continue &lt;br&gt;
record_click(key, request_context) 

&lt;p&gt;return create_redirect_response(original_url) &lt;br&gt;
&lt;/p&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  The API router calls these functions based on request type&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;app = route_request({ &lt;br&gt;
    "POST /shorten": handle_create_url, &lt;br&gt;
    "GET /{key}": handle_redirect &lt;br&gt;
}) &lt;/p&gt;

&lt;p&gt;if &lt;strong&gt;name&lt;/strong&gt; == "&lt;strong&gt;main&lt;/strong&gt;": &lt;br&gt;
    app.run() &lt;/p&gt;

&lt;p&gt;Notice: &lt;/p&gt;

&lt;p&gt;Each block is called as a simple function &lt;br&gt;
Error handling at the integration layer catches failures from any block &lt;br&gt;
The orchestration logic is explicit and readable &lt;br&gt;
No block knows about the others — they communicate only through the interfaces defined in their Prompts &lt;br&gt;
2.5 File Structure Summary &lt;/p&gt;

&lt;p&gt;The final project has the following structure: &lt;/p&gt;

&lt;p&gt;project/ &lt;br&gt;
├── url_validator.py      # header + generated code &lt;br&gt;
├── key_generator.py      # header + generated code &lt;br&gt;
├── storage_manager.py    # header + generated code &lt;br&gt;
├── redirect_handler.py   # header + generated code &lt;br&gt;
├── analytics_recorder.py # header + generated code &lt;br&gt;
├── api_router.py         # header + generated code &lt;br&gt;
└── main.py               # integration (no header needed) &lt;/p&gt;

&lt;p&gt;Each .py file is self-contained. A human can open any file, read the Description to understand what it does, read the Prompt to see the requirements, and see the generated code below. The system is complete and runnable. &lt;/p&gt;

&lt;p&gt;2.6 Summary of the Four Phases &lt;/p&gt;

&lt;p&gt;Phase &lt;br&gt;
Human Role &lt;br&gt;
AI Role &lt;br&gt;
Output &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Decomposition 
Define block boundaries 
Suggest, clarify, critique 
List of functional blocks &lt;/li&gt;
&lt;li&gt;Block Specs 
Write Description and Prompt in .py file header 
Review, suggest improvements 
.py file with header (no code yet) &lt;/li&gt;
&lt;li&gt;Generation 
Copy Prompt to AI, review generated code, paste into file 
Generate code from Prompt 
.py file with header + working code &lt;/li&gt;
&lt;li&gt;Integration 
Define orchestration, validate 
Generate glue code, tests 
Working system &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;2.7 Key Benefits Demonstrated &lt;/p&gt;

&lt;p&gt;Benefit &lt;br&gt;
How It Appears &lt;br&gt;
Manageable pieces &lt;br&gt;
The URL shortener was broken into 6 independent blocks &lt;br&gt;
Clear interfaces &lt;br&gt;
Each block's Prompt defined inputs, outputs, and error handling &lt;br&gt;
AI works where it excels &lt;br&gt;
Each block was generated from a focused, detailed Prompt &lt;br&gt;
Human controls integration &lt;br&gt;
The main.py orchestration was written and validated by the human &lt;br&gt;
Reproducible &lt;br&gt;
Any block can be regenerated from its Prompt at any time &lt;br&gt;
Maintainable &lt;br&gt;
Changing one block does not affect others &lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>python</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Putting AI-Generated Blocks into Your Working System-1</title>
      <dc:creator>karllui</dc:creator>
      <pubDate>Thu, 30 Apr 2026 17:54:27 +0000</pubDate>
      <link>https://dev.to/karllui/putting-ai-generated-blocks-into-your-working-system-45p7</link>
      <guid>https://dev.to/karllui/putting-ai-generated-blocks-into-your-working-system-45p7</guid>
      <description>&lt;p&gt;Part 1: Why Vibe Coding Breaks Down &lt;/p&gt;

&lt;p&gt;Last month, I spent an afternoon building a URL shortener with Claude. &lt;/p&gt;

&lt;p&gt;The first prompt worked beautifully. Code appeared. Tests passed. I felt like a wizard. &lt;/p&gt;

&lt;p&gt;By the fifth prompt, things got weird. The AI added features I did not ask for. It changed the database schema twice. It could not remember what the API endpoints were supposed to be. &lt;/p&gt;

&lt;p&gt;By the tenth prompt, I was not coding. I was negotiating with a machine that had forgotten the conversation we had twenty minutes ago. &lt;/p&gt;

&lt;p&gt;This is not a failure of AI. This is the failure of the method. &lt;/p&gt;

&lt;p&gt;Most of us use AI the same way we use a search engine: we ask for something, we get an answer, we move on. That works for recipes and trivia. It does not work for building software. &lt;/p&gt;

&lt;p&gt;Because AI has a hidden limit. Not a technical limit — a structural one. And once you see it, you cannot unsee it. &lt;/p&gt;

&lt;p&gt;In this series, I will show you that limit. Then I will show you a simple way around it. &lt;/p&gt;

&lt;p&gt;The solution is not a better prompt. It is a different way to think about the work. &lt;/p&gt;

&lt;p&gt;What if the problem was never the AI? &lt;/p&gt;

&lt;p&gt;1.1 The Pattern: It Starts So Well &lt;/p&gt;

&lt;p&gt;You have felt this. Everyone who has built anything non-trivial with AI has felt this. &lt;/p&gt;

&lt;p&gt;You sit down with Claude, GPT, or Copilot. You start a new project. The first few exchanges feel like magic. &lt;/p&gt;

&lt;p&gt;"Build me a URL shortener API." &lt;/p&gt;

&lt;p&gt;Code appears. Beautiful, working code. You test it. It works. You are elated. &lt;/p&gt;

&lt;p&gt;"Now add analytics so I can see how many times each short link was clicked." &lt;/p&gt;

&lt;p&gt;The AI adds it. Still works. Two features done. &lt;/p&gt;

&lt;p&gt;"Add user accounts so people can manage their own links." &lt;/p&gt;

&lt;p&gt;The AI adds it. But now things start breaking. &lt;/p&gt;

&lt;p&gt;The database schema from feature 1 does not quite fit. The authentication logic from feature 3 conflicts with the analytics query from feature 2. The AI tries to fix it, but introduces regressions. You try to clarify. The context window fills up. The AI loses track of earlier decisions. &lt;/p&gt;

&lt;p&gt;You are no longer coding. You are herding cats with a keyboard. &lt;/p&gt;

&lt;p&gt;This is "vibe coding" — casually prompting an AI to generate code, hoping it all holds together. It works for tiny scripts. It works for demos. But for real projects? It collapses under its own weight. &lt;/p&gt;

&lt;p&gt;Why? &lt;/p&gt;

&lt;p&gt;1.2 The Hidden Limit You Have Probably Noticed But Never Named &lt;/p&gt;

&lt;p&gt;Here is a simple experiment you can run yourself. &lt;/p&gt;

&lt;p&gt;Task A (Small and Focused): &lt;/p&gt;

&lt;p&gt;Write a Python function that takes a URL string and returns True if it is a valid URL, False otherwise. Handle edge cases like missing protocols, invalid characters, and malformed domains. &lt;/p&gt;

&lt;p&gt;The AI will likely produce a clean, correct, well-commented function in seconds. Quality: Excellent. &lt;/p&gt;

&lt;p&gt;Task B (Large and Ambiguous): &lt;/p&gt;

&lt;p&gt;Build a complete URL shortener service with a web interface, a REST API, user accounts, click analytics, and a database. Use Python. &lt;/p&gt;

&lt;p&gt;The AI will produce something. But the result will be fragile. The authentication piece might not integrate cleanly with the analytics piece. The database schema might be inconsistent. Quality: Poor to Mediocre. &lt;/p&gt;

&lt;p&gt;Same AI. Same model. Same capabilities. &lt;/p&gt;

&lt;p&gt;The only difference is the size and scope of the task. &lt;/p&gt;

&lt;p&gt;LLMs have a context window — a limit to how much information they can hold in working memory at once. Give them a small, self-contained problem, and they operate within that window comfortably. Give them a large system design, and they spill over the edges. They forget earlier decisions. They contradict themselves. &lt;/p&gt;

&lt;p&gt;But there is a deeper insight here. A more important one. &lt;/p&gt;

&lt;p&gt;1.3 The New Design Method That Changes Everything &lt;/p&gt;

&lt;p&gt;AI does not think like a system architect. It does not hold a complete mental model of your project, with all its interconnections and trade-offs. &lt;/p&gt;

&lt;p&gt;AI thinks in functions. &lt;/p&gt;

&lt;p&gt;It understands: &lt;/p&gt;

&lt;p&gt;"Given input X, produce output Y" &lt;br&gt;
"Validate this string" &lt;br&gt;
"Query that database table" &lt;br&gt;
"Format this response" &lt;br&gt;
It does not naturally understand: &lt;/p&gt;

&lt;p&gt;How the URL validator should coordinate with the key generator &lt;br&gt;
Whether the storage manager should be called before or after analytics logging &lt;br&gt;
What happens when the redirect handler cannot find a key &lt;br&gt;
These are integration concerns — and they are not the AI's strength. &lt;/p&gt;

&lt;p&gt;Most developers, when encountering AI's limitations on large tasks, do one of two things: &lt;/p&gt;

&lt;p&gt;Give up — "AI is not ready for real projects" &lt;br&gt;
Push harder — "Let me write a longer, more detailed prompt" &lt;br&gt;
Both miss the point. &lt;/p&gt;

&lt;p&gt;The correct response is to change how you structure the work: &lt;/p&gt;

&lt;p&gt;Do not ask the AI to build the system. Ask the AI to build the functions. You connect the functions into the system. &lt;/p&gt;

&lt;p&gt;1.4 What This Unlocks &lt;/p&gt;

&lt;p&gt;An AI can write an excellent URL validator. An AI can write an excellent key generator. An AI can write an excellent storage manager. An AI can write an excellent redirect handler. &lt;/p&gt;

&lt;p&gt;Each of these is a functional block — a self-contained unit with a clear input, a clear output, and no hidden dependencies. &lt;/p&gt;

&lt;p&gt;The AI's job is to implement each block. &lt;/p&gt;

&lt;p&gt;Your job — the human's job — is to: &lt;/p&gt;

&lt;p&gt;Define what the blocks are &lt;br&gt;
Specify how they connect &lt;br&gt;
Validate that the connections work &lt;br&gt;
This is not "AI does everything." This is AI and human working symbiotically. Each doing what they do best. &lt;/p&gt;

&lt;p&gt;Before (Vibe Coding) &lt;br&gt;
After (FBD) &lt;br&gt;
One giant prompt for the whole system &lt;br&gt;
Many small prompts, one per block &lt;br&gt;
AI loses context, contradicts itself &lt;br&gt;
Each block's context is small and focused &lt;br&gt;
Integration happens accidentally &lt;br&gt;
Integration is explicit and designed &lt;br&gt;
Hard to debug (which block failed?) &lt;br&gt;
Each block can be tested in isolation &lt;br&gt;
Changes require regenerating large portions &lt;br&gt;
Change one block, leave others untouched &lt;/p&gt;

&lt;p&gt;1.5 What Is Coming in Part 2 and Part 3 &lt;/p&gt;

&lt;p&gt;In Part 2, we will introduce Functional Block Design — a simple, repeatable methodology that turns this insight into practice. You will learn: &lt;/p&gt;

&lt;p&gt;How to decompose a system into functional blocks &lt;br&gt;
How to write a Block Spec (Description for humans, Prompt for AI) &lt;br&gt;
How to generate code from the Prompt &lt;br&gt;
How to store everything in one .py file &lt;br&gt;
In Part 3, we will build the complete URL shortener — all six blocks, integrated into a working system. &lt;/p&gt;

&lt;p&gt;By the end of this series, you will have a repeatable way to turn AI-generated code into systems that actually work together. &lt;/p&gt;

&lt;p&gt;No more herding cats. &lt;/p&gt;

&lt;p&gt;Cover image generated with Grok / xAI&lt;/p&gt;

</description>
      <category>ai</category>
      <category>tutorial</category>
      <category>softwareengineering</category>
      <category>python</category>
    </item>
  </channel>
</rss>
