backend / app.py
logeswari's picture
msg
aca9ade
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel,Field
import pandas as pd
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO, # Set the logging level to INFO
format="%(asctime)s - %(levelname)s - %(message)s",
handlers=[
logging.FileHandler("app.log"), # Log to a file named app.log
logging.StreamHandler() # Log to the console
]
)
# Create logger instance
logger = logging.getLogger(__name__)
app = FastAPI()
file_path = "D:/backend1/world_population.csv"
try:
countries_df = pd.read_csv(file_path)
# Convert Population and Area to numeric values with error handling
countries_df["Population"] = pd.to_numeric(countries_df["Population"])
countries_df["Area"] = pd.to_numeric(countries_df["Area"])
logger.info("CSV file loaded and processed successfully.")
except Exception as e:
logger.error(f"Failed to load or process CSV file: {e}")
raise
# Pydantic models for API response
class CountryPopulation(BaseModel):
country: str
population: int
class ContinentPopulationResponse(BaseModel):
continent: str=Field(description="continent of country")
total_population: int
total_area: int
continent_population_density: float
max_population: CountryPopulation
min_population: CountryPopulation
avg_population: int
@app.get("/")
def home():
logger.info("Accessed home endpoint.")
return {"message": "Welcome to the World Population API"}
@app.get("/continent/{continent_name}", response_model=ContinentPopulationResponse)
def get_continent_population(continent_name: str):
try:
logger.info(f"Received request for continent: {continent_name}")
# Filter data for the given continent
continent_group = countries_df[countries_df["Continent"] == continent_name]
continent_group = continent_group.dropna(subset=["Population", "Area"])
if continent_group.empty:
logger.warning(f"No data found for continent: {continent_name}")
raise HTTPException(status_code=404, detail=f"No data found for continent: {continent_name}")
# Calculate total population and total area
total_population = int(continent_group["Population"].sum())
total_area = int(continent_group["Area"].sum())
# Handle case where total_area is zero to avoid division by zero
if total_area == 0:
logger.error(f"Total area is zero for continent: {continent_name}. Cannot calculate population density.")
raise HTTPException(status_code=400, detail="Total area is zero. Cannot calculate population density.")
# Calculate population density
continent_density = total_population / total_area
# Find max and min population countries
max_row = continent_group.loc[continent_group["Population"].idxmax()]
min_row = continent_group.loc[continent_group["Population"].idxmin()]
avg_population = int(continent_group["Population"].mean())
logger.info(
f"Processed data for continent: {continent_name} | "
f"Total Population: {total_population}, Total Area: {total_area}, "
f"Population Density: {continent_density:.2f}"
)
return ContinentPopulationResponse(
continent=continent_name,
total_population=total_population,
total_area=total_area,
continent_population_density=continent_density,
max_population=CountryPopulation(
country=max_row["Country"],
population=int(max_row["Population"])
),
min_population=CountryPopulation(
country=min_row["Country"],
population=int(min_row["Population"])
),
avg_population=avg_population
)
except HTTPException as http_err:
# Log and re-raise HTTP-specific exceptions
logger.error(f"HTTP exception occurred: {http_err.detail}")
raise http_err
except Exception as e:
# Handle unexpected errors
logger.error(f"Unexpected error occurred while processing continent: {continent_name} | Error: {e}")
raise HTTPException(status_code=500, detail="An unexpected error occurred while processing your request.")