Initial API (Kingdom + KF3)

This commit is contained in:
2023-08-24 22:02:10 +02:00
commit 12df873ead
21 changed files with 1150 additions and 0 deletions

View File

27
resources/KF3/friend.py Normal file
View File

@@ -0,0 +1,27 @@
from flask_restful import Resource
from flask import current_app as app
from flask import request
import json
class KF3_Friend(Resource):
def get(self, id:int):
if "wiki" in request.args:
result = app.databases["KF3"].get_chara_wiki(id)
response = app.response_class(
response=result,
status=200,
mimetype='text/plain'
)
else:
result = app.databases["KF3"].get_chara(id)
result = json.dumps(result)
response = app.response_class(
response=result,
status=200,
mimetype='application/json'
)
response.headers.add("Access-Control-Allow-Origin", "*")
return response

21
resources/KF3/friends.py Normal file
View File

@@ -0,0 +1,21 @@
import json
from flask_restful import Resource
from flask import current_app as app
class KF3_Friends(Resource):
def get(self):
db = app.databases["KF3"]
result = []
for value in db.charaData.values():
result.append({"id": value["id"], "name": value["nameEn"]})
result = sorted(result, key=lambda f: f["id"])
response = app.response_class(
response=json.dumps(result, ensure_ascii=False, indent=1),
status=200,
mimetype='application/json'
)
response.headers.add("Access-Control-Allow-Origin", "*")
return response

View File

@@ -0,0 +1,25 @@
from flask_restful import Resource
from flask import current_app as app
from flask import request
class Kingdom_Friend(Resource):
def get(self, id:int):
if "wiki" in request.args:
result = app.databases["Kingdom"].get_chara_wiki(id)
response = app.response_class(
response=result,
status=200,
mimetype='text/plain'
)
else:
result = app.databases["Kingdom"].get_chara(id)
response = app.response_class(
response=result,
status=200,
mimetype='application/json'
)
response.headers.add("Access-Control-Allow-Origin", "*")
return response

View File

@@ -0,0 +1,21 @@
import json
from flask_restful import Resource
from flask import current_app as app, jsonify
class Kingdom_Friends(Resource):
def get(self):
db = app.databases["Kingdom"]
result = []
for value in db.processed_friends.values():
result.append({"id": value["sn"], "name": value["name"], "describe": value["describe"]["content"] if "content" in value["describe"] else ""})
result = sorted(result, key=lambda f: f["id"])
response = app.response_class(
response=json.dumps(result, ensure_ascii=False, indent=1),
status=200,
mimetype='application/json'
)
response.headers.add("Access-Control-Allow-Origin", "*")
return response

16
resources/Kingdom/item.py Normal file
View File

@@ -0,0 +1,16 @@
from flask_restful import Resource
from flask import current_app as app
from flask import request
class Kingdom_Item(Resource):
def get(self, id:int):
result = app.databases["Kingdom"].get_item(id)
response = app.response_class(
response=result,
status=200,
mimetype='application/json'
)
response.headers.add("Access-Control-Allow-Origin", "*")
return response

View File

@@ -0,0 +1,23 @@
import json
from flask_restful import Resource
from flask import current_app as app, jsonify
class Kingdom_Items(Resource):
def get(self):
db = app.databases["Kingdom"]
result = []
for key in db.kfk_en_item.indexed_data.keys():
new_value = db.kfk_en_item.indexed_data[key]
new_value["id"] = key
result.append(new_value)
result = sorted(result, key=lambda f: f["id"])
response = app.response_class(
response=json.dumps(result, ensure_ascii=False, indent=1),
status=200,
mimetype='application/json'
)
response.headers.add("Access-Control-Allow-Origin", "*")
return response

36
resources/average.py Normal file
View File

@@ -0,0 +1,36 @@
import requests
from datetime import datetime
from flask_restful import Resource
from flask import jsonify, make_response
from resources.shared import API_URL, VALID_CURRENCIES_A, ERROR_CURRENCY_CODE, ERROR_DATE_FORMAT, ERROR_NO_DATA
class AverageRate(Resource):
def get(self, date : str, currency : str):
"""
Returns average exchange rate for the specified currency and date.
Weekends and holidays return code 404.
"""
if not currency.upper() in VALID_CURRENCIES_A:
return make_response(jsonify({"error": ERROR_CURRENCY_CODE}), 400)
try:
date_temp = datetime.strptime(date, "%Y-%m-%d")
if date_temp.weekday() in [5,6]:
return make_response(jsonify({"error": ERROR_NO_DATA}), 404)
#ensure correct date string format
date = date_temp.strftime("%Y-%m-%d")
except:
return make_response(jsonify({"error": ERROR_DATE_FORMAT}), 400)
url = f"{API_URL}/exchangerates/rates/a/{currency}/{date}/"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
return make_response(jsonify({"mid": data["rates"][0]["mid"]}), 200)
elif response.status_code == 404:
return make_response(jsonify({"error": ERROR_NO_DATA}), 404)
else:
return make_response(jsonify({"error": response.text}), 400)

View File

@@ -0,0 +1,34 @@
import requests
from flask_restful import Resource
from flask import jsonify, make_response
from resources.shared import API_URL, ERROR_CURRENCY_CODE, ERROR_DATE_RANGE, VALID_CURRENCIES_C
class DifferenceLast(Resource):
def get(self, currency : str, num_days : int):
"""
Returns the highest difference between "ask" and "bid" values, and the day it occured.
Weekends and holidays are skipped and do not count towards the 'num_days' limit."
"""
if not currency.upper() in VALID_CURRENCIES_C:
return make_response(jsonify({"error": ERROR_CURRENCY_CODE}), 400)
if not (num_days > 0 and num_days < 256):
return make_response(jsonify({"error": ERROR_DATE_RANGE}), 400)
url = f"{API_URL}/exchangerates/rates/c/{currency}/last/{num_days}/"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
result = {"diff_max": 0, "date":""}
for rate in data["rates"]:
#ensure correct precision
difference = round(rate["ask"] - rate["bid"],4)
#spread can be negative on rare occasions
if abs(difference) > abs(result["diff_max"]):
result["diff_max"] = difference
result["date"] = rate["effectiveDate"]
return make_response(jsonify(result), 200)
else:
return make_response(jsonify({"error": response.text}), 400)

38
resources/minmax_last.py Normal file
View File

@@ -0,0 +1,38 @@
import requests
from flask_restful import Resource
from flask import jsonify, make_response
from resources.shared import API_URL, ERROR_CURRENCY_CODE, ERROR_DATE_RANGE, VALID_CURRENCIES_A
class MinMaxLast(Resource):
def get(self, currency : str, num_days : int):
"""
Returns minimum and maximum average exchange rate values, and the days they occured.
Weekends and holidays are skipped and do not count towards the 'num_days' limit."
"""
if not currency.upper() in VALID_CURRENCIES_A:
return make_response(jsonify({"error": ERROR_CURRENCY_CODE}), 400)
if not (num_days > 0 and num_days < 256):
return make_response(jsonify({"error": ERROR_DATE_RANGE}), 400)
url = f"{API_URL}/exchangerates/rates/a/{currency}/last/{num_days}/"
response = requests.get(url)
if response.status_code == 200:
data = response.json()
result = {"mid_min": data["rates"][0]["mid"], "date_min":"", "mid_max": data["rates"][0]["mid"], "date_max":""}
for rate in data["rates"]:
#if rates are equal, return the more recent one
#recent values are at the end of the list
if rate["mid"] >= result["mid_max"]:
result["mid_max"] = rate["mid"]
result["date_max"] = rate["effectiveDate"]
if rate["mid"] <= result["mid_min"]:
result["mid_min"] = rate["mid"]
result["date_min"] = rate["effectiveDate"]
return make_response(jsonify(result), 200)
else:
return make_response(jsonify({"error": response.text}), 400)

13
resources/shared.py Normal file
View File

@@ -0,0 +1,13 @@
# Root url for the NBP API
API_URL = "https://api.nbp.pl/api/"
# List of currencies accepted by NBP as of 2023-04-21
# https://nbp.pl/en/statistic-and-financial-reporting/rates/table-a/
# https://nbp.pl/en/statistic-and-financial-reporting/rates/table-c/
VALID_CURRENCIES_A = ["AUD","THB","BRL","BGN","CAD","CLP","CZK","DKK","EUR","HUF","HKD","UAH","ISK","INR","MYR","MXN","ILS","NZD","NOK","PHP","GBP","ZAR","RON","IDR","SGD","SEK","CHF","TRY","USD","KRW","JPY","CNY","XDR" ]
VALID_CURRENCIES_C = ["AUD","CAD","CZK","DKK","EUR","HUF","NOK","GBP","SEK","CHF","USD","JPY","XDR"]
ERROR_CURRENCY_CODE = "Invalid currency code."
ERROR_DATE_FORMAT = "Incorrect date format, expected YYYY-MM-DD"
ERROR_DATE_RANGE = "Invalid currency code."
ERROR_NO_DATA = "Exchange rate data is not available for this date."