feat: add annotations about functionalities of some endpoints
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# API is expected to return:
|
||||
# API is expected to return a tuple of:
|
||||
# - HTTP status code,
|
||||
# - human-readable status message,
|
||||
# - json with appropriate data
|
||||
@@ -11,6 +11,14 @@ import lewy_db as ldb
|
||||
import lewy_globals
|
||||
|
||||
def require_authentication(func):
|
||||
"""
|
||||
Ten dekorator służy do wymuszenia parametru "token"
|
||||
podczas obsługi zapytania. Powinien on zostać doklejony
|
||||
do żądania, np. /api/v1/halt?token=XXX...
|
||||
Wartość tokenu jest pobierana z pola api_key w config.toml.
|
||||
Jeżeli skrypt jej tam nie znajdzie, jest generowana losowo
|
||||
na starcie i drukowana w terminalu.
|
||||
"""
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
token = kwargs["r"].args.get('token')
|
||||
@@ -26,19 +34,44 @@ def require_authentication(func):
|
||||
return wrapper
|
||||
|
||||
def increment_bad_requests():
|
||||
"""
|
||||
Zwiększa globalny, tymczasowy licznik nieprawidłowych zapytań.
|
||||
"""
|
||||
lewy_globals.apiFailedRequests += 1
|
||||
|
||||
def not_implemented(data):
|
||||
"""
|
||||
Zwraca kod 501 wraz z endpointem, który wywołał błąd.
|
||||
|
||||
:param data: Ścieżka zapytania
|
||||
:type data: list
|
||||
"""
|
||||
# TODO: change list to string -> data, not data[0]
|
||||
return 501, f"not recognised/implemented: {data[0]}", []
|
||||
|
||||
# GET /api/v1
|
||||
def stub_hello():
|
||||
"""
|
||||
Prosta funkcja witająca użytkowników w /api/v1
|
||||
"""
|
||||
return 200, 'hello from v1! stats are at /api/v1/stats', []
|
||||
|
||||
def epoch_to_date(epoch):
|
||||
"""
|
||||
Zamienia Unix'owy epoch na lokalny czas,
|
||||
w formacie przypominającym format ISO.
|
||||
|
||||
:param epoch: Epoch - sekundy po 1. stycznia 1970
|
||||
:type epoch: int
|
||||
"""
|
||||
return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(epoch))
|
||||
|
||||
# GET /api/v1/
|
||||
# GET /api/v1/stats
|
||||
def stats():
|
||||
"""
|
||||
Zwraca ogólne statystyki serwera.
|
||||
"""
|
||||
data_to_send = {
|
||||
"start_time": lewy_globals.starttime,
|
||||
"uptime": lewy_globals.getUptime(),
|
||||
@@ -50,11 +83,20 @@ def stats():
|
||||
}
|
||||
return 200, "ok", data_to_send
|
||||
|
||||
def get_matches():
|
||||
# GET /api/v1/matches
|
||||
def get_matches(r):
|
||||
"""
|
||||
TODO: Zwraca mecze.
|
||||
"""
|
||||
pass
|
||||
|
||||
# GET /api/v1/debugger_halt?token=XXX...
|
||||
@require_authentication
|
||||
def debugger_halt(r):
|
||||
"""
|
||||
Zatrzymuje wykonywanie skryptu, aby pozwolić
|
||||
administratorowi na wykonywanie dowolnego polecenia z konsoli.
|
||||
"""
|
||||
if lewy_globals.config['general']['is_proxied']:
|
||||
print(f"{c.WARNING}[{epoch_to_date(time.time())}]{c.ENDC} {r.headers['X-Forwarded-For']} triggered a debugger halt!")
|
||||
else:
|
||||
@@ -63,6 +105,16 @@ def debugger_halt(r):
|
||||
return 200, "ok", []
|
||||
|
||||
def lookup(data, request):
|
||||
"""
|
||||
Obsługuje zapytania zwrócone do /api/v1/...
|
||||
|
||||
:param data: Lista ze ścieżką zapytania
|
||||
:type data: list
|
||||
:param request: Zapytanie
|
||||
:type request: flask.request
|
||||
|
||||
:returns: Wartość zwróconą przez którąś z przywołanych funkcji.
|
||||
"""
|
||||
if data == []:
|
||||
return stub_hello()
|
||||
match data[0].lower():
|
||||
@@ -74,6 +126,8 @@ def lookup(data, request):
|
||||
return stub_hello()
|
||||
case 'halt':
|
||||
return debugger_halt(r = request)
|
||||
case 'matches':
|
||||
get_matches(r = request)
|
||||
case _:
|
||||
increment_bad_requests()
|
||||
return not_implemented(data)
|
||||
@@ -29,7 +29,7 @@ def safeTraverse(obj: dict, path: list, default=None):
|
||||
finally:
|
||||
return result
|
||||
|
||||
def getCommit():
|
||||
def getCommit() -> str | None:
|
||||
try:
|
||||
return Repo(search_parent_directories=True).head.object.hexsha
|
||||
except Exception as e:
|
||||
@@ -65,7 +65,7 @@ def ensureRandomlyGeneratedPassword():
|
||||
print(f"{colors.WARNING}WARNING{colors.ENDC}: Default config populated with one-time, insecure pseudorandom API key: {colors.OKCYAN}{randomly_generated_passcode}{colors.ENDC}.\n"
|
||||
f" The API key is not the Flask debugger PIN. You need to provide a config file for persistence!{colors.ENDL}")
|
||||
|
||||
def getConfig(configfile):
|
||||
def getConfig(configfile: str) -> dict:
|
||||
global randomly_generated_passcode
|
||||
|
||||
if not os.path.exists(configfile):
|
||||
@@ -82,15 +82,26 @@ def getConfig(configfile):
|
||||
else:
|
||||
return toml.load(configfile)
|
||||
|
||||
def setupDb(app, config):
|
||||
def setupDb(app, config) -> lewy_db.baza:
|
||||
global db
|
||||
db = lewy_db.baza(app, config)
|
||||
return db
|
||||
|
||||
def getDb():
|
||||
def getDb() -> lewy_db.baza:
|
||||
"""
|
||||
Akcesor dla wrappera bazy danych wspólnego dla całego projektu
|
||||
(klasy baza z lewy_db)
|
||||
"""
|
||||
return db
|
||||
|
||||
def setConfig(configfile):
|
||||
"""
|
||||
Zapewnia, że konfiguracja nie jest pusta,
|
||||
nawet, gdy sam plik jest pusty.
|
||||
|
||||
:param configfile: Ścieżka do pliku
|
||||
:type configfile: str
|
||||
"""
|
||||
global config
|
||||
config = getConfig(configfile)
|
||||
|
||||
@@ -100,6 +111,11 @@ def setConfig(configfile):
|
||||
|
||||
|
||||
def getHeaders():
|
||||
"""
|
||||
Zwraca hardkodowane nagłówki do scrapowania, bądź te,
|
||||
z config.toml (o ile użytkownik jakieś podał).
|
||||
"""
|
||||
|
||||
# NOTE: use ESR user-agent
|
||||
# user_agent = 'Mozilla/5.0 (Windows NT 10.0; rv:130.0) Gecko/20100101 Firefox/130.0'
|
||||
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:128.0) Gecko/20100101 Firefox/128.0'
|
||||
@@ -110,10 +126,18 @@ def getHeaders():
|
||||
return user_agent
|
||||
|
||||
def getUptime():
|
||||
"""
|
||||
Zwraca informację o czasie działania serwera.
|
||||
"""
|
||||
return int(time.time()) - starttime
|
||||
|
||||
def extractIpAndPortFromPublicUrl() -> tuple:
|
||||
|
||||
"""
|
||||
Pobiera dane z konfiguracji i zwraca
|
||||
krotkę: adres IP i port.
|
||||
"""
|
||||
|
||||
ip, port = "127.0.0.1", "5000"
|
||||
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user