Spaces:
Running
Running
api parse token
Browse files- README.md +5 -0
- main.py +49 -19
- requirements.txt +4 -0
- scratch/test_dataset_to_dict.py +15 -0
- scratch/test_glob.py +6 -0
- utils.py +56 -0
README.md
CHANGED
|
@@ -10,3 +10,8 @@ short_description: log displayer for all end
|
|
| 10 |
---
|
| 11 |
|
| 12 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
---
|
| 11 |
|
| 12 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
| 13 |
+
|
| 14 |
+
Please set following environment variables:
|
| 15 |
+
|
| 16 |
+
- `hf_token`: hugginface token
|
| 17 |
+
- `SECRET_KEY`: key of parsing user token
|
main.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
| 1 |
-
from fastapi import FastAPI, Body
|
| 2 |
from fastapi.middleware.cors import CORSMiddleware
|
| 3 |
-
from
|
| 4 |
-
import
|
| 5 |
-
from
|
| 6 |
-
|
| 7 |
|
| 8 |
app = FastAPI(
|
| 9 |
title=f"Log Displayer",
|
|
@@ -19,25 +19,55 @@ app.add_middleware(
|
|
| 19 |
allow_headers=["*"],
|
| 20 |
)
|
| 21 |
print("Done\n")
|
| 22 |
-
add_applications(page.page, app=app, title="Log Displayer")
|
| 23 |
-
|
| 24 |
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
|
| 32 |
|
| 33 |
-
@app.post("/
|
| 34 |
-
async def
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
return True
|
| 39 |
|
| 40 |
|
| 41 |
@app.get("/healthcheck")
|
| 42 |
async def health_check():
|
| 43 |
-
return True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI, Body, Header, Request
|
| 2 |
from fastapi.middleware.cors import CORSMiddleware
|
| 3 |
+
from utils import beijing, parse_token
|
| 4 |
+
from logging_helper import LoggingHelper
|
| 5 |
+
from fastapi.templating import Jinja2Templates
|
| 6 |
+
|
| 7 |
|
| 8 |
app = FastAPI(
|
| 9 |
title=f"Log Displayer",
|
|
|
|
| 19 |
allow_headers=["*"],
|
| 20 |
)
|
| 21 |
print("Done\n")
|
|
|
|
|
|
|
| 22 |
|
| 23 |
+
LOGS_REPO_ID = "pgsoft/logs"
|
| 24 |
+
local_dir = "data/logs"
|
| 25 |
+
logger = LoggingHelper(
|
| 26 |
+
repo_id=LOGS_REPO_ID,
|
| 27 |
+
local_dir=local_dir,
|
| 28 |
+
)
|
| 29 |
|
| 30 |
|
| 31 |
+
@app.post("/{end}")
|
| 32 |
+
async def add_log(
|
| 33 |
+
end: str,
|
| 34 |
+
message: str = Body(..., embed=True),
|
| 35 |
+
token: str | None = Header(None),
|
| 36 |
+
source: str | None = Header("web"),
|
| 37 |
+
):
|
| 38 |
+
print("Type: ", end)
|
| 39 |
+
print("From: ", source)
|
| 40 |
+
print("Token: ", token)
|
| 41 |
+
uid, username = parse_token(token)
|
| 42 |
+
timestamp = beijing().isoformat()
|
| 43 |
+
print("Timestamp: ", timestamp)
|
| 44 |
+
print("Message: ", message)
|
| 45 |
+
log = {
|
| 46 |
+
"type": end,
|
| 47 |
+
"source": source,
|
| 48 |
+
"uid": uid,
|
| 49 |
+
"username": username,
|
| 50 |
+
"token": token,
|
| 51 |
+
"content": message,
|
| 52 |
+
"timestamp": timestamp,
|
| 53 |
+
}
|
| 54 |
+
logger.addlog(log)
|
| 55 |
return True
|
| 56 |
|
| 57 |
|
| 58 |
@app.get("/healthcheck")
|
| 59 |
async def health_check():
|
| 60 |
+
return True
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
templates = Jinja2Templates(directory="static")
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
@app.get("")
|
| 67 |
+
@app.get("/")
|
| 68 |
+
async def root(request: Request):
|
| 69 |
+
data = logger.refresh()
|
| 70 |
+
return templates.TemplateResponse(
|
| 71 |
+
"index.html",
|
| 72 |
+
{"request": request, "data": data},
|
| 73 |
+
)
|
requirements.txt
CHANGED
|
@@ -4,3 +4,7 @@ transformers
|
|
| 4 |
numpy
|
| 5 |
torch
|
| 6 |
aiohttp
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
numpy
|
| 5 |
torch
|
| 6 |
aiohttp
|
| 7 |
+
python-jose[cryptography]
|
| 8 |
+
apscheduler==3.11.0
|
| 9 |
+
huggingface-hub==0.34.4
|
| 10 |
+
datasets==4.0.0
|
scratch/test_dataset_to_dict.py
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import datasets as ds
|
| 2 |
+
import pandas as pd
|
| 3 |
+
import glob
|
| 4 |
+
|
| 5 |
+
dataset = ds.Dataset.from_dict({})
|
| 6 |
+
files = glob.glob("**/*.json", root_dir="data/logs", recursive=True)
|
| 7 |
+
for file in files:
|
| 8 |
+
path = "data/logs/" + file
|
| 9 |
+
temp = ds.Dataset.from_json(path)
|
| 10 |
+
dataset = ds.concatenate_datasets([dataset, temp]) # type: ignore
|
| 11 |
+
df = dataset.to_pandas()
|
| 12 |
+
assert isinstance(df, pd.DataFrame)
|
| 13 |
+
print(len(df))
|
| 14 |
+
res = df.to_dict(orient="records")
|
| 15 |
+
print(res)
|
scratch/test_glob.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import glob
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
path = "data/logs"
|
| 5 |
+
files = glob.glob("**/*.json", root_dir=path, recursive=True)
|
| 6 |
+
print(files)
|
utils.py
CHANGED
|
@@ -1,7 +1,63 @@
|
|
| 1 |
from datetime import datetime
|
| 2 |
from zoneinfo import ZoneInfo
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 3 |
|
| 4 |
|
| 5 |
def beijing():
|
| 6 |
"""get beijing time"""
|
| 7 |
return datetime.now(tz=ZoneInfo("Asia/Shanghai"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
from datetime import datetime
|
| 2 |
from zoneinfo import ZoneInfo
|
| 3 |
+
from typing import Any
|
| 4 |
+
from jose import jwt
|
| 5 |
+
import hashlib
|
| 6 |
+
import json
|
| 7 |
+
import uuid
|
| 8 |
+
import os
|
| 9 |
+
|
| 10 |
+
|
| 11 |
+
SECRET_KEY = os.environ.get("SECRET_KEY")
|
| 12 |
|
| 13 |
|
| 14 |
def beijing():
|
| 15 |
"""get beijing time"""
|
| 16 |
return datetime.now(tz=ZoneInfo("Asia/Shanghai"))
|
| 17 |
+
|
| 18 |
+
|
| 19 |
+
def decode_jwt(token: str) -> dict[str, Any]:
|
| 20 |
+
"""get payload in the jwt token"""
|
| 21 |
+
assert SECRET_KEY, "Please set the environment variable SECRET_KEY"
|
| 22 |
+
return jwt.decode(token, SECRET_KEY, algorithms=["HS256"])
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def parse_token(token: str | None) -> tuple[str, str]:
|
| 26 |
+
"""parse user token to get uid and username
|
| 27 |
+
|
| 28 |
+
:param token (str): jwt token
|
| 29 |
+
:return (str, str): (uid, username)
|
| 30 |
+
"""
|
| 31 |
+
if not token:
|
| 32 |
+
uid, username = "no_uid", "Anonymous"
|
| 33 |
+
else:
|
| 34 |
+
payload: dict = decode_jwt(token)
|
| 35 |
+
uid = payload.get("uid", "no_uid")
|
| 36 |
+
username = payload.get("username", "Anonymous")
|
| 37 |
+
print(f"UID: {uid}")
|
| 38 |
+
print(f"Username: {username}")
|
| 39 |
+
return uid, username
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
def md5(text: list[str | bytes] | str | bytes | None = None) -> str:
|
| 43 |
+
"""generate the md5 hash code of the given text, if text is None,
|
| 44 |
+
return a random md5"""
|
| 45 |
+
code = hashlib.md5()
|
| 46 |
+
if text:
|
| 47 |
+
if isinstance(text, str):
|
| 48 |
+
text = text.encode("utf-8")
|
| 49 |
+
code.update(text)
|
| 50 |
+
elif isinstance(text, list):
|
| 51 |
+
for t in text:
|
| 52 |
+
if isinstance(t, str):
|
| 53 |
+
t = t.encode("utf-8")
|
| 54 |
+
code.update(t)
|
| 55 |
+
else:
|
| 56 |
+
code.update(text)
|
| 57 |
+
else:
|
| 58 |
+
code.update(uuid.uuid4().bytes)
|
| 59 |
+
return code.hexdigest()
|
| 60 |
+
|
| 61 |
+
|
| 62 |
+
def json_to_str(obj: dict | list) -> str:
|
| 63 |
+
return json.dumps(obj, separators=(",", ":"))
|