šŸš€Building Agents for a Simple Microservice Architecture with FastAPI (Part 2)

Estimated read time 7 min read

Ā 

Previous Blog :Ā Ā Building Collaborative Microservices in Python with FastAPI: Echo & Reverse Agents (Beginner -Part1)

Microservices are a powerful way to design scalable and maintainable applications.

In this blog, we will explore a minimal yet effective microservice setup usingĀ FastAPI, perfect for learning and experimentation. This will help to you build better Microservices and deploy in SAP BTP – Kyma

Sample Use Case

A client sends a city name to the Weather Agent. The agent fetches enrichment data from the Data Enricher, generates fake weather data, and returns a combined report. This mimics real-world API composition and data aggregation.

Overview

It consists of two core services:

Fake Weather AgentĀ (weather_agent.py)Data EnricherĀ (data_enricher.py)

A shell script (run.sh) is included to launch both services on separate ports, simulating a real-world microservice environment.

šŸŒ¦ļø 1. Fake Weather Agent (weather_agent.py)

Purpose:Ā  Ā Generates a fake weather report for a given city.

API Endpoint:Ā Ā POST /weather — Accepts a JSON payload with a city name.

How It Works:

Receives a city name from the client.Optionally calls theĀ Data EnricherĀ service to fetch additional info (e.g., population, country).Generates random weather data:TemperatureCondition (e.g., sunny, rainy)HumidityWind speedReturns a combined weather report, enriched with city metadata if available.

Tech Stack:

FastAPI for API developmentPydantic for data validationhttpx for asynchronous HTTP callsfrom fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx
import os
import random

PORT = int(os.getenv(“PORT”, 8002))
TARGET = os.getenv(“TARGET_URL”, “http://localhost:8003”) # downstream agent

app = FastAPI(title=”Fake-Weather-Agent”)

class Location(BaseModel):
city: str

class WeatherReport(BaseModel):
source: str
city: str
temperature: float # °C
condition: str
humidity: int # %
wind_kmh: float

CONDITIONS = [“Sunny”, “Cloudy”, “Rain”, “Snow”, “Thunderstorm”]

@app.post(“/weather”, response_model=WeatherReport)
async def get_weather(loc: Location):
“””Generate a fake weather report for the given city.”””
# Optionally call another agent (e.g. a ā€œdata-enrichmentā€ service)
async with httpx.AsyncClient() as client:
try:
r = await client.post(
f”{TARGET}/enrich”,
json={“city”: loc.city}
)
r.raise_for_status()
extra = r.json()
except Exception:
extra = {}

return WeatherReport(
source=”Fake-Weather-Agent”,
city=loc.city,
temperature=round(random.uniform(-10, 40), 1),
condition=random.choice(CONDITIONS),
humidity=random.randint(20, 95),
wind_kmh=round(random.uniform(0, 40), 1),
**extra
)

šŸ™ļø 2. Data Enricher (data_enricher.py)

Purpose:Ā Provides additional metadata about a city.

API Endpoint:Ā POST /enrich — Accepts a JSON payload with a city name.

How It Works:

Looks up the city in a fake in-memory database.Returns population and country if found.If not found, returns default placeholder values.

Tech Stack:

FastAPIPydanticfrom fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI(title=”Data-Enricher”)

class EnrichRequest(BaseModel):
city: str

class EnrichResponse(BaseModel):
population: int
country: str

FAKE_DB = {
“london”: {“population”: 9_000_000, “country”: “UK”},
“paris”: {“population”: 2_100_000, “country”: “France”},
“tokyo”: {“population”: 14_000_000, “country”: “Japan”},
}

@app.post(“/enrich”, response_model=EnrichResponse)
def enrich(req: EnrichRequest):
city = req.city.lower()
if city not in FAKE_DB:
return EnrichResponse(population=0, country=”Unknown”)
return FAKE_DB[city]

šŸ–„ļø 3. Running the Services (run.sh)

Purpose:Ā Starts both services usingĀ uvicorn, FastAPI’s ASGI server.
A shell script (run.sh) is provided to run both services on different ports.

How It Works:

LaunchesĀ Fake Weather AgentĀ on portĀ 8002LaunchesĀ Data EnricherĀ on portĀ 8003Each service runs in its own terminal window# Terminal 1
uvicorn fake_weather:app –port 8002 –reload

# Terminal 2
uvicorn data_enricher:app –port 8003 –reload

Key Points :Ā 

Microservice Communication:
The Weather Agent calls the Data Enricher via HTTP to demonstrate service-to-service communication.Extensibility:
Easy to add more enrichment services or expand the fake database.FastAPI Features:
Shows how to use Pydantic models, async endpoints, and response models.Local Development:Ā Ā 
Simple to run both services locally for testing and learning.Ā 

​  Previous Blog :Ā Ā Building Collaborative Microservices in Python with FastAPI: Echo & Reverse Agents (Beginner -Part1)Microservices are a powerful way to design scalable and maintainable applications. In this blog, we will explore a minimal yet effective microservice setup usingĀ FastAPI, perfect for learning and experimentation. This will help to you build better Microservices and deploy in SAP BTP – KymaSample Use CaseA client sends a city name to the Weather Agent. The agent fetches enrichment data from the Data Enricher, generates fake weather data, and returns a combined report. This mimics real-world API composition and data aggregation.OverviewIt consists of two core services:Fake Weather AgentĀ (weather_agent.py)Data EnricherĀ (data_enricher.py)A shell script (run.sh) is included to launch both services on separate ports, simulating a real-world microservice environment.šŸŒ¦ļø 1. Fake Weather Agent (weather_agent.py)Purpose:Ā  Ā Generates a fake weather report for a given city.API Endpoint:Ā Ā POST /weather — Accepts a JSON payload with a city name.How It Works:Receives a city name from the client.Optionally calls theĀ Data EnricherĀ service to fetch additional info (e.g., population, country).Generates random weather data:TemperatureCondition (e.g., sunny, rainy)HumidityWind speedReturns a combined weather report, enriched with city metadata if available.Tech Stack:FastAPI for API developmentPydantic for data validationhttpx for asynchronous HTTP callsfrom fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import httpx
import os
import random

PORT = int(os.getenv(“PORT”, 8002))
TARGET = os.getenv(“TARGET_URL”, “http://localhost:8003”) # downstream agent

app = FastAPI(title=”Fake-Weather-Agent”)

class Location(BaseModel):
city: str

class WeatherReport(BaseModel):
source: str
city: str
temperature: float # °C
condition: str
humidity: int # %
wind_kmh: float

CONDITIONS = [“Sunny”, “Cloudy”, “Rain”, “Snow”, “Thunderstorm”]

@app.post(“/weather”, response_model=WeatherReport)
async def get_weather(loc: Location):
“””Generate a fake weather report for the given city.”””
# Optionally call another agent (e.g. a ā€œdata-enrichmentā€ service)
async with httpx.AsyncClient() as client:
try:
r = await client.post(
f”{TARGET}/enrich”,
json={“city”: loc.city}
)
r.raise_for_status()
extra = r.json()
except Exception:
extra = {}

return WeatherReport(
source=”Fake-Weather-Agent”,
city=loc.city,
temperature=round(random.uniform(-10, 40), 1),
condition=random.choice(CONDITIONS),
humidity=random.randint(20, 95),
wind_kmh=round(random.uniform(0, 40), 1),
**extra
)šŸ™ļø 2. Data Enricher (data_enricher.py)Purpose:Ā Provides additional metadata about a city.API Endpoint:Ā POST /enrich — Accepts a JSON payload with a city name.How It Works:Looks up the city in a fake in-memory database.Returns population and country if found.If not found, returns default placeholder values.Tech Stack:FastAPIPydanticfrom fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI(title=”Data-Enricher”)

class EnrichRequest(BaseModel):
city: str

class EnrichResponse(BaseModel):
population: int
country: str

FAKE_DB = {
“london”: {“population”: 9_000_000, “country”: “UK”},
“paris”: {“population”: 2_100_000, “country”: “France”},
“tokyo”: {“population”: 14_000_000, “country”: “Japan”},
}

@app.post(“/enrich”, response_model=EnrichResponse)
def enrich(req: EnrichRequest):
city = req.city.lower()
if city not in FAKE_DB:
return EnrichResponse(population=0, country=”Unknown”)
return FAKE_DB[city]šŸ–„ļø 3. Running the Services (run.sh)Purpose:Ā Starts both services usingĀ uvicorn, FastAPI’s ASGI server.A shell script (run.sh) is provided to run both services on different ports.How It Works:LaunchesĀ Fake Weather AgentĀ on portĀ 8002LaunchesĀ Data EnricherĀ on portĀ 8003Each service runs in its own terminal window# Terminal 1
uvicorn fake_weather:app –port 8002 –reload

# Terminal 2
uvicorn data_enricher:app –port 8003 –reloadKey Points :Ā Microservice Communication:The Weather Agent calls the Data Enricher via HTTP to demonstrate service-to-service communication.Extensibility:Easy to add more enrichment services or expand the fake database.FastAPI Features:Shows how to use Pydantic models, async endpoints, and response models.Local Development:Ā Ā Simple to run both services locally for testing and learning.Ā Ā Ā Read MoreĀ Technology Blog Posts by SAP articlesĀ 

#SAP

#SAPTechnologyblog

You May Also Like

More From Author