Skip to content

Commit c11e253

Browse files
authored
Merge pull request #21 from WoongyuChoi/dev
Dev
2 parents 17537c3 + de24247 commit c11e253

File tree

9 files changed

+118
-17
lines changed

9 files changed

+118
-17
lines changed

api/data_processor.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class DataProcessor:
99
"""
1010

1111
@staticmethod
12-
def process_exchange_rate_data(response_data):
12+
def process_statistic_data(response_data):
1313
if "StatisticSearch" not in response_data:
1414
logger.error(f"ValueError: {str(response_data)}")
1515

@@ -27,8 +27,8 @@ def process_exchange_rate_data(response_data):
2727
processed_data.append(
2828
{
2929
"value": value,
30-
"item_code": row.get("ITEM_CODE1"),
31-
"item_name": row.get("ITEM_NAME1"),
30+
"itemCode": row.get("ITEM_CODE1"),
31+
"itemName": row.get("ITEM_NAME1"),
3232
"time": row.get("TIME"),
3333
"unit": (
3434
row.get("UNIT_NAME").strip() if row.get("UNIT_NAME") else None

api/external.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,25 @@ def fetch_exchange_rate(start_date, end_date, item_code=None):
4848
url = generate_statistic_url(params)
4949
response_data = fetch_data(url)
5050

51-
return DataProcessor.process_exchange_rate_data(response_data)
51+
return DataProcessor.process_statistic_data(response_data)
52+
53+
@staticmethod
54+
@default_params
55+
def fetch_foreign_reserves(start_month, end_month):
56+
"""
57+
외부 API를 호출하여 외환보유액 데이터를 조회합니다.
58+
"""
59+
60+
params = APIParams(
61+
service_name="StatisticSearch",
62+
table_code="732Y001",
63+
period="M",
64+
start_date=start_month,
65+
end_date=end_month,
66+
item_code="99",
67+
)
68+
69+
url = generate_statistic_url(params)
70+
response_data = fetch_data(url)
71+
72+
return DataProcessor.process_statistic_data(response_data)

api/server.py

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import time
22

3-
from flask import Flask, jsonify, request
3+
from flask import Flask, jsonify
44
from flask_caching import Cache
55

66
from api import ExternalAPI
77
from config import Config
8+
from decorators import json_utf8_response
89
from handler.exception_handler import register_exception_handlers
910
from handler.logger import get_logger
1011
from utils import get_request_params
@@ -20,7 +21,6 @@
2021

2122
@app.route("/")
2223
def health_check():
23-
logger.info("Health check called.")
2424
status = {
2525
"status": "UP",
2626
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
@@ -36,6 +36,7 @@ def favicon(ext):
3636

3737

3838
@app.route("/api/exchange-rate", methods=["GET"])
39+
@json_utf8_response
3940
@cache.cached(query_string=True)
4041
def get_exchange_rate():
4142
params = get_request_params("start_date", "end_date", "item_code")
@@ -45,8 +46,20 @@ def get_exchange_rate():
4546
end_date=params["end_date"],
4647
item_code=params["item_code"],
4748
)
48-
logger.info("Exchange rate data fetched successfully.")
49-
return jsonify(data), 200
49+
return data, 200
50+
51+
52+
@app.route("/api/foreign-reserves", methods=["GET"])
53+
@cache.cached(query_string=True)
54+
@json_utf8_response
55+
def get_foreign_reserves():
56+
params = get_request_params("start_month", "end_month")
57+
58+
data = ExternalAPI.fetch_foreign_reserves(
59+
start_month=params["start_month"],
60+
end_month=params["end_month"],
61+
)
62+
return data, 200
5063

5164

5265
def handler(event, context):

config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ class Config:
22
CACHE_TYPE = "FileSystemCache"
33
CACHE_DIR = "/tmp"
44
CACHE_DEFAULT_TIMEOUT = 60
5+
JSON_AS_ASCII = False

decorators/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
from .param_defaults import default_params
2+
from .json_response import json_utf8_response
23

3-
__all__ = ["default_params"]
4+
__all__ = [
5+
"default_params",
6+
"json_utf8_response",
7+
]

decorators/json_response.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from functools import wraps
2+
from flask import Response
3+
import json
4+
5+
6+
def json_utf8_response(func):
7+
@wraps(func)
8+
def wrapper(*args, **kwargs):
9+
result, status_code = func(*args, **kwargs)
10+
return Response(
11+
json.dumps(result, ensure_ascii=False),
12+
mimetype="application/json",
13+
status=status_code,
14+
)
15+
16+
return wrapper

decorators/param_defaults.py

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,35 @@
1+
import inspect
12
from functools import wraps
2-
from utils import get_first_day_of_last_month, get_last_day_of_last_month
3+
4+
from utils import (
5+
get_first_day_of_last_month,
6+
get_first_month_of_last_year,
7+
get_last_day_of_last_month,
8+
get_last_month_of_last_year,
9+
)
310

411

512
def default_params(func):
613
@wraps(func)
714
def wrapper(*args, **kwargs):
8-
kwargs["start_date"] = kwargs.get("start_date") or get_first_day_of_last_month()
9-
kwargs["end_date"] = kwargs.get("end_date") or get_last_day_of_last_month()
15+
func_signature = inspect.signature(func)
16+
func_params = func_signature.parameters
17+
18+
if "start_date" in func_params:
19+
kwargs["start_date"] = (
20+
kwargs.get("start_date") or get_first_day_of_last_month()
21+
)
22+
if "end_date" in func_params:
23+
kwargs["end_date"] = kwargs.get("end_date") or get_last_day_of_last_month()
24+
if "start_month" in func_params:
25+
kwargs["start_month"] = (
26+
kwargs.get("start_month") or get_first_month_of_last_year()
27+
)
28+
if "end_month" in func_params:
29+
kwargs["end_month"] = (
30+
kwargs.get("end_month") or get_last_month_of_last_year()
31+
)
32+
1033
return func(*args, **kwargs)
1134

1235
return wrapper

utils/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
1-
from .date_utils import get_first_day_of_last_month, get_last_day_of_last_month
1+
from .date_utils import (
2+
get_first_day_of_last_month,
3+
get_last_day_of_last_month,
4+
get_first_month_of_last_year,
5+
get_last_month_of_last_year,
6+
)
27
from .fetch_utils import fetch_data, generate_statistic_url
38
from .request_utils import get_request_params
49

510
__all__ = [
611
"get_first_day_of_last_month",
712
"get_last_day_of_last_month",
13+
"get_first_month_of_last_year",
14+
"get_last_month_of_last_year",
815
"fetch_data",
916
"generate_statistic_url",
1017
"get_request_params",

utils/date_utils.py

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44

55
def get_first_day_of_last_month():
66
"""
7-
지난달의 첫날을 반환합니다.
8-
:return: 지난달의 첫날 (YYYYMMDD 형식)
7+
지난달의 첫날(yyyyMMdd)을 반환합니다.
98
"""
109
today = datetime.today()
1110
last_day_of_last_month = today.replace(day=1) - timedelta(days=1)
@@ -15,9 +14,26 @@ def get_first_day_of_last_month():
1514

1615
def get_last_day_of_last_month():
1716
"""
18-
지난달의 마지막 날을 반환합니다.
19-
:return: 지난달의 마지막 날 (YYYYMMDD 형식)
17+
지난달의 마지막 날(yyyyMMdd)을 반환합니다.
2018
"""
2119
today = datetime.today()
2220
last_day_of_last_month = today.replace(day=1) - timedelta(days=1)
2321
return last_day_of_last_month.strftime("%Y%m%d")
22+
23+
24+
def get_first_month_of_last_year():
25+
"""
26+
지난 해의 첫 달(yyyyMM)을 반환합니다.
27+
"""
28+
today = datetime.today()
29+
first_month = today.replace(year=today.year - 1, month=1, day=1)
30+
return first_month.strftime("%Y%m")
31+
32+
33+
def get_last_month_of_last_year():
34+
"""
35+
지난 해의 마지막 달(yyyyMM)을 반환합니다.
36+
"""
37+
today = datetime.today()
38+
last_month = today.replace(year=today.year - 1, month=12, day=1)
39+
return last_month.strftime("%Y%m")

0 commit comments

Comments
 (0)