[[{“value”:”
Â
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:
- Temperature
- Condition (e.g., sunny, rainy)
- Humidity
- Wind speed
- Returns a combined weather report, enriched with city metadata if available.
Tech Stack:
- FastAPI for API development
- Pydantic for data validation
- httpx for asynchronous HTTP calls
from 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:
- FastAPI
- Pydantic
from 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 8002
- Launches Data Enricher on port 8003
- Each 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.
“}]]Â
 [[{“value”:” 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Â
#SAPCHANNEL