Ā
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