""" This module defines the route for fetching a chart for a specific currency pair and period. It includes the endpoint `/api/getChart/{period}` which allows users to request a chart for a given currency pair (from_currency and conv_currency) over a specified time period (week, month, quarter, or year). """ from datetime import datetime from dateutil.relativedelta import relativedelta from fastapi import APIRouter, status, Request, Response from function.create_chart import create_chart router = APIRouter() @router.get("/api/getChart/{period}", status_code=status.HTTP_201_CREATED) async def get_chart_period( response: Response, request: Request, from_currency: str = None, conv_currency: str = None, period: str = None, ): """ Fetches a chart for a given currency pair and a specific period. The period can be one of the following: 'week', 'month', 'quarter', 'year'. Based on the selected period, it calculates the start date and retrieves the chart data. :param response: The response object used to set status and message. :param request: The request object used to retrieve details of the incoming request. :param from_currency: The base currency in the pair (e.g., 'USD'). :param conv_currency: The target currency in the pair (e.g., 'EUR'). :param period: The time period for which the chart is requested (e.g., 'week', 'month', 'quarter', 'year'). :return: A response containing the chart URL or an error message if parameters are invalid. """ if not from_currency or not conv_currency: response.status_code = status.HTTP_400_BAD_REQUEST return { 'status': status.HTTP_400_BAD_REQUEST, 'message': 'The from_currency and conv_currency fields are required.', } if period not in ['week', 'month', 'quarter', 'year']: response.status_code = status.HTTP_400_BAD_REQUEST return {'message': 'Invalid period.', 'status_code': status.HTTP_400_BAD_REQUEST} days, month, years = 0, 0, 0 if period == 'week': days = -7 elif period == 'month': month = -1 elif period == 'quarter': month = -3 elif period == 'year': years = -1 end_date = datetime.now() start_date = end_date + relativedelta(months=month, days=days, years=years) chart = await create_chart( from_currency, conv_currency, start_date.strftime('%Y-%m-%d'), end_date.strftime('%Y-%m-%d') ) return await prepare_chart_response(response, request, chart) async def prepare_chart_response( response: Response, request: Request, chart_name: str ): """ Prepares the response to return the URL of the generated chart. If the chart data is not found, it returns a 404 error with an appropriate message. Otherwise, it returns a URL to access the chart image. :param response: The response object used to set status and message. :param request: The request object used to retrieve details of the incoming request. :param chart_name: The name of the generated chart (used to build the URL). :return: A dictionary with the chart URL or an error message if no chart is found. """ if not chart_name: response.status_code = status.HTTP_404_NOT_FOUND return {'message': 'No data found.', 'status_code': status.HTTP_404_NOT_FOUND} host = request.headers.get("host") url_schema = request.url.scheme return { 'status': status.HTTP_201_CREATED, 'message': f'{url_schema}://{host}/static/charts/{chart_name}.png', }