Download audio: https://dts.podtrac.com/redirect.mp3/api.spreaker.com/download/episode/68548644/dotnetrocks_1976_old_developers_using_new_tools.mp3
Yesterday we started exploring GitHub Spark. We looked at the basic prompting experience, the live preview but also explored the visual editing features and the specification generation (through a PRD.md file). But we didn't have the time to check out all the features.
Let's dive in...
This is where Spark really shines. Unlike standalone vibe coding tools, Spark can create a GitHub repository from your project. Once created you get a repository with GitHub Actions, Dependabot, and all the standard tooling. The code is synchronized so you don’t need to leave the vibe coding experience.
Remark: This is also a great way to better understand what is going on behind the scenes. It allowed me to fix some issues where I wasn’t able to solve it inside GitHub Spark.
Need more power? Open a Codespace directly from Spark and continue development with the full GitHub ecosystem at your fingertips.
You don’t have to start with only a prompt but you can also start from an existing design or sketch you draw on a napkin. Take a picture and attach it to the Spark's input field, together with the following example prompt.
Spark has built-in authentication, since users need to sign in with their GitHub account to access your app. You control who has access to your app by setting visibility and data access options.
When you're ready, click "Publish" and your app goes live on Microsoft Azure with built-in authentication and a secure URL. No DevOps knowledge required.
GitHub Spark uses your existing GitHub Copilot plan. Each prompt consumes 4 premium requests, which draw from your plan's premium request allowance. (More info here: GitHub Spark billing - GitHub Docs)
I think that GitHub Spark certainly has its place among the other vibe coding tools. In addition, it offers some unique features like the visual editor and of course the great GitHub integration that makes it a compelling candidate.
My main wish is that the used model will still improve as it got stuck a few times. The good news was that I was always able to fix it by switching to the repository and do some changes there (using GitHub Copilot).
I used Github Spark to create a 7 minutes workout application. The 7-minute workout is a high-intensity circuit training routine designed to deliver maximum fitness benefits in minimal time using just body weight, a chair, and a wall.
I started doing this workout every day with my oldest son and we noticed that we had 2 problems;
So we decided to build an app that walks you through the routine and keeps track of the time. Timing and the exact exercise are shared through audio cues so you don’t have to look at your cellphone during the routine.
The app is available here (you only need a GitHub account to be able to access it):
As organizations accelerate their adoption of Generative AI, one reality is becoming increasingly clear: modern GenAI systems cannot rely on static knowledge. The world they operate in changes too quickly — customer expectations shift in minutes, social sentiment evolves in real time, and internal policies or operational data update continuously.
In this environment, the traditional approach of embedding documents once, storing them in a vector database, and occasionally refreshing the index is no longer enough. It creates a fundamental disconnect between what the system knows and what is actually happening.
This is why real-time Retrieval-Augmented Generation (RAG) must be treated as an integral architectural consideration, not an optional enhancement. It determines whether a GenAI system remains accurate, trustworthy, and aligned with current data.
If your system relies on stale knowledge:
Real-time RAG changes that. It ensures modern GenAI systems:
This shift isn’t cosmetic — it’s architectural.
It’s the difference between deploying AI that remembers the past versus AI that understands the present.
As GenAI becomes foundational across industries — powering customer service, decision support, automation, and insights — engineering for real-time context is no longer optional. It’s the new baseline.
At its core, real-time Retrieval-Augmented Generation follows a continuous cycle:
Stream → Embed → Store → Retrieve → Generate → Attribute.

This cycle keeps GenAI systems aligned with live information rather than stagnant data.
The architecture ensures that intelligence remains synchronized with the environment it operates in.
Take the example of brand sentiment tracking. You don’t need yesterday’s conversation — you need right now.
A real-time RAG pipeline can:
Instead of delayed dashboards, you get a real-time view of what’s happening.
This is the same paradigm used by real-time streaming systems described by AWS and Google Cloud for near-instantaneous insight pipelines.
Now imagine a customer asking:
“Is the premium plan still available?”
If your AI relies on stale or nightly-refreshed data, it won’t reflect what changed two minutes ago.
Real-time RAG solves this by:
This transforms a chatbot or voice agent from a static FAQ engine into a dynamic, context-aware intelligence layer.
Frameworks like LangChain and LlamaIndex now provide built-in primitives for streaming retrieval and context refresh, enabling these capabilities at scale.
A robust real-time RAG architecture typically includes:
Use Kafka, Amazon Kinesis, or Google Pub/Sub to capture new events instantly.
This prevents reliance on slow batch processes.
Only newly changed content should be re-embedded.
This keeps latency low and cost manageable.
Choose a vector store capable of:
Pinecone, Milvus, Weaviate, and pgvector are common options.
LLMs retrieve both relevant and recent chunks before generating outputs.
Streaming responses improve the user experience and reduce perceived latency.
Every answer must show where the information came from and when it was last updated.
This is critical for trust and alignment with governance standards.
We’re entering an era where AI must operate with situational awareness, not just static knowledge.
Systems that cannot adapt in real time will feel outdated — because they are.
Real-time RAG represents the architectural shift that enables AI to:
The organizations that embrace this architecture will build AI systems that are not only intelligent, but aware. And awareness — especially in a fast-moving world — is the real advantage.
References:
## 1 Building Uber’s Dynamic Pricing Engine in .NET: Supply-Demand Algorithms, Geospatial Indexing, and Real-Time Market Simulation
Uber’s pricing engine is one of the most fascinating real-time systems ever deployed at scale. It balances millions of drivers and riders across constantly changing geographies, optimizing prices every few seconds to match market conditions. In this article, we’ll reconstruct that core system — not the entire Uber stack, but the essential architectural, algorithmic, and engineering ideas that power dynamic pricing — using modern *.NET 8/9* technologies.
We’ll move from concept to implementation: building event-driven microservices, handling live geospatial data, calculating real-time supply-demand ratios, and integrating predictive models with *ML.NET*. The focus is on production-grade architecture — code that can run at scale, not just a toy simulation.
### 1.1 The Business Imperative: Beyond “Surge”
Most people think “surge pricing” is about profit. It’s not — it’s about market equilibrium. When too many riders request rides and too few drivers are available, prices must rise to restore balance. The system isn’t punishing demand; it’s broadcasting scarcity. The goal is threefold:
In software development, you’ll run into XML (Extensible Markup Language) when working with configuration files, API responses, data exports, and more. While there are powerful third-party libraries for parsing XML, Python's standard library already includes everything you need.
In this tutorial, you'll learn how to parse XML using Python's built-in xml.etree.ElementTree module. No pip installs required.
🔗 You can find the code on GitHub.
To follow along with this tutorial, you should have:
Python 3.7 or later installed on your system
Basic understanding of Python syntax and data structures
Familiarity with basic programming concepts like loops and conditionals
A text editor or IDE for writing Python code
No external libraries are required as we'll use Python's built-in xml.etree.ElementTree module.
Let's start simple. We'll parse XML directly from a string to understand the fundamental concepts.
import xml.etree.ElementTree as ET
xml_string = """
<catalog>
<product id="101">
<name>Wireless Keyboard</name>
<price currency="USD">29.99</price>
</product>
</catalog>
"""
root = ET.fromstring(xml_string)
print(f"Root tag: {root.tag}")
print(f"Root attributes: {root.attrib}")
How this works:
We import xml.etree.ElementTree and give it the alias ET (this is the convention)
ET.fromstring() parses the XML string and returns the root element
Every element has a .tag property (the element name) and .attrib dictionary (its attributes)
The root object represents the <catalog> element in our XML
For the above example, you’ll see the following output:
Root tag: catalog
Root attributes: {}
Here, the root.attrib is empty because the root element <catalog> in the provided xml_string does not have any attributes defined. Attributes are key-value pairs within the opening tag of an XML element, like id="101" or currency="USD" in the <product> and <price> elements. Since <catalog> only has a tag and no additional information within its opening tag, its attributes dictionary is empty.
In real applications, you'll usually read XML from files. Say you have a products.xml file. Here's how you can read from the XML file:
# Parse an XML file
tree = ET.parse('products.xml')
root = tree.getroot()
print(f"Root element: {root.tag}")
Before we proceed to run and check the output, let’s note the differences between reading XML strings vs files:
ET.parse() reads from a file and returns an ElementTree object
We call .getroot() to get the root element
Use ET.parse() for files, ET.fromstring() for strings
Running the above code should give you:
Root element: catalog
ElementTree gives you three main ways to search for elements. Understanding when to use each is important.
import xml.etree.ElementTree as ET
xml_data = """
<catalog>
<product id="101">
<name>Wireless Keyboard</name>
<categories>
<category>Electronics</category>
<category>Accessories</category>
</categories>
</product>
<product id="102">
<name>USB Mouse</name>
<categories>
<category>Electronics</category>
</categories>
</product>
</catalog>
"""
root = ET.fromstring(xml_data)
# Method 1: find() - returns the FIRST matching element
first_product = root.find('product')
print(f"First product ID: {first_product.get('id')}")
# Method 2: findall() - returns ALL direct children that match
all_products = root.findall('product')
print(f"Total products: {len(all_products)}")
# Method 3: iter() - recursively finds ALL matching elements
all_categories = root.iter('category')
category_list = [cat.text for cat in all_categories]
print(f"All categories: {category_list}")
Now let’s understand how the three methods work:
find() stops at the first match. Use when you only need one element.
findall() only searches direct children (one level deep). Use for immediate child elements.
iter() searches recursively through the entire tree. Use when elements might be nested anywhere.
This is important: findall('category') on root won't find anything because <category> isn't a direct child of <catalog>. But iter('category') will find all categories no matter how deeply nested. So when you run the above code, you’ll get:
First product ID: 101
Total products: 2
All categories: ['Electronics', 'Accessories', 'Electronics']
Now let's extract actual data from our XML. This is where you turn structured XML into Python data you can work with.
xml_data = """
<catalog>
<product id="101">
<name>Wireless Keyboard</name>
<price currency="USD">29.99</price>
<stock>45</stock>
</product>
</catalog>
"""
root = ET.fromstring(xml_data)
product = root.find('product')
# Get element text content
product_name = product.find('name').text
price_text = product.find('price').text
stock_text = product.find('stock').text
# Get attributes (two ways)
product_id = product.get('id') # Method 1: .get()
product_id_alt = product.attrib['id'] # Method 2: .attrib dictionary
# Get nested attributes
price_element = product.find('price')
currency = price_element.get('currency')
print(f"Product: {product_name}")
print(f"ID: {product_id}")
print(f"Price: {currency} {price_text}")
print(f"Stock: {stock_text}")
This outputs:
Product: Wireless Keyboard
ID: 101
Price: USD 29.99
Stock: 45
What's happening here:
.text gets the text content between opening and closing tags
.get('attribute_name') safely retrieves an attribute (returns None if missing)
.attrib['attribute_name'] accesses the attribute dictionary directly (raises KeyError if missing)
Use .get() when an attribute might be optional, use .attrib[] when it's required
Let's put it all together with a practical example. We'll parse the full product catalog and convert it to a Python list of dictionaries.
def parse_product_catalog(xml_file):
"""Parse an XML product catalog and return a list of product dictionaries."""
tree = ET.parse(xml_file)
root = tree.getroot()
products = []
for product_element in root.findall('product'):
# Extract product data
product = {
'id': product_element.get('id'),
'name': product_element.find('name').text,
'price': float(product_element.find('price').text),
'currency': product_element.find('price').get('currency'),
'stock': int(product_element.find('stock').text),
'categories': []
}
# Extract categories (nested elements)
categories_element = product_element.find('categories')
if categories_element is not None:
for category in categories_element.findall('category'):
product['categories'].append(category.text)
products.append(product)
return products
Breaking down this parser:
We iterate through all <product> elements using findall()
For each product, we extract text and attributes into a dictionary. We convert numeric strings to proper types (float for price, int for stock)
For nested categories, we first check if the <categories> element exists. Then we iterate through child <category> elements and collect their text
The result is clean Python data structures you can easily work with. You can now use the parser like so:
products = parse_product_catalog('products.xml')
for product in products:
print(f"\nProduct: {product['name']}")
print(f" ID: {product['id']}")
print(f" Price: {product['currency']} {product['price']}")
print(f" Stock: {product['stock']}")
print(f" Categories: {', '.join(product['categories'])}")
Output:
Product: Wireless Keyboard
ID: 101
Price: USD 29.99
Stock: 45
Categories: Electronics, Accessories
Product: USB Mouse
ID: 102
Price: USD 15.99
Stock: 120
Categories: Electronics
Real-world XML is messy (no surprises there!). Elements might be missing, text might be empty, or attributes might not exist. Here's how to handle that gracefully.
xml_data = """
<catalog>
<product id="101">
<name>Wireless Keyboard</name>
<price currency="USD">29.99</price>
</product>
<product id="102">
<name>USB Mouse</name>
<!-- Missing price element -->
</product>
</catalog>
"""
root = ET.fromstring(xml_data)
for product in root.findall('product'):
name = product.find('name').text
# Safe way to handle potentially missing elements
price_element = product.find('price')
if price_element is not None:
price = float(price_element.text)
currency = price_element.get('currency', 'USD') # Default value
print(f"{name}: {currency} {price}")
else:
print(f"{name}: Price not available")
Here, we handle potential missing data by:
Using product.find('price') to search for the <price> element within the current <product> element.
Checking if the result of find() is None. If an element is not found, find() returns None.
Using an if price_element is not None: condition to only attempt to access the text (price_element.text) and attributes (price_element.get('currency', 'USD')) of the <price> element if it was actually found.
Adding an else block to handle the case where the <price> element is missing, printing "Price not available".
This approach prevents errors that would occur if you tried to access .text or .get() on a None object. For the above code snippet, you’ll get:
Wireless Keyboard: USD 29.99
USB Mouse: Price not available
Here are a few more error-handling strategies:
Always check if find() returns None before accessing .text or .get()
Use .get('attr', 'default') to provide default values for missing attributes
Consider wrapping parsing in try-except blocks for production code
Validate your data after parsing rather than assuming XML structure is correct
You now know how to parse XML in Python without installing any external libraries. You learned:
How to read XML from strings and files
The difference between find(), findall(), and iter()
How to extract text content and attributes safely
How to handle nested elements and missing data
The xml.etree.ElementTree module works well enough for most XML parsing needs, and it's always available in Python's standard library.
For more advanced XML navigation and selection, you can explore XPath expressions. XPath works well for selecting nodes in an XML document and can be very useful for complex structures. We’ll cover this in another tutorial.
Until then, happy parsing!
Explore critical data quality rules and learn to implement them without pre-built tools by using SQL scripting techniques.
The post A Practical Guide to Implement Data Quality Rules in SQL Server appeared first on MSSQLTips.com.