File size: 4,343 Bytes
833b787
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aca9ade
833b787
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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.")