🚀Building Agents  for a Simple Microservice Architecture with FastAPI (Part 2)
Share

[[{“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.

Yogananda_0-1754809227004.png

🌦️ 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:

  1. Receives a city name from the client.
  2. Optionally calls the Data Enricher service to fetch additional info (e.g., population, country).
  3. Generates random weather data:
    • Temperature
    • Condition (e.g., sunny, rainy)
    • Humidity
    • Wind speed
  4. 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:

  1. Looks up the city in a fake in-memory database.
  2. Returns population and country if found.
  3. 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

By ali