mirror of
https://github.com/uw935/vatsimfox.git
synced 2026-09-17 04:48:58 +00:00
Merge pull request #13 from uw935/feature/fastapi
v1.3: Backend rewrite to FastAPI
This commit is contained in:
+1
-1
@@ -9,4 +9,4 @@ RUN pip install -r requirements.txt
|
|||||||
|
|
||||||
COPY . /build/
|
COPY . /build/
|
||||||
|
|
||||||
CMD ["python3", "-m", "flask", "run", "--host=0.0.0.0"]
|
CMD ["python3", "app.py"]
|
||||||
+100
-25
@@ -1,41 +1,116 @@
|
|||||||
|
import uvicorn
|
||||||
import requests
|
import requests
|
||||||
from flask import Flask, render_template, abort, request, jsonify
|
|
||||||
|
from fastapi import (
|
||||||
|
FastAPI,
|
||||||
|
Request,
|
||||||
|
HTTPException,
|
||||||
|
)
|
||||||
|
from fastapi.responses import FileResponse
|
||||||
|
from starlette.staticfiles import StaticFiles
|
||||||
|
from fastapi.templating import Jinja2Templates
|
||||||
|
|
||||||
|
|
||||||
app = Flask(__name__)
|
|
||||||
VATSIM_API_URL = "https://api.vatsim.net/v2/"
|
VATSIM_API_URL = "https://api.vatsim.net/v2/"
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
@app.route("/")
|
title="VATSIM Fox",
|
||||||
def index_page():
|
docs_url=None,
|
||||||
return render_template("index.html")
|
redoc_url=None,
|
||||||
|
openapi_url=None,
|
||||||
|
redirect_slashes=True
|
||||||
|
)
|
||||||
|
templates = Jinja2Templates(directory="templates")
|
||||||
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
|
|
||||||
|
|
||||||
@app.errorhandler(404)
|
@app.get("/")
|
||||||
def errorhandler_page(_):
|
async def get_index_page(request: Request):
|
||||||
return render_template("4O4.html"), 404
|
"""
|
||||||
|
Index page
|
||||||
|
|
||||||
|
:param request: FastAPI request
|
||||||
|
:return: HTML template
|
||||||
|
"""
|
||||||
|
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
name="index.html",
|
||||||
|
context={
|
||||||
|
"request": request,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/request")
|
@app.get("/favicon.ico", include_in_schema=False)
|
||||||
def request_handler():
|
async def get_favicon():
|
||||||
if request_string := request.args.get("request_string"):
|
"""
|
||||||
|
Get favicon
|
||||||
|
|
||||||
|
:return: Icon file
|
||||||
|
"""
|
||||||
|
|
||||||
|
return FileResponse("./static/icon.ico")
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/{cid}/")
|
||||||
|
async def get_viewer_page(request: Request, cid: str = None):
|
||||||
|
"""
|
||||||
|
Viewer page
|
||||||
|
|
||||||
|
:param request: FastAPI request
|
||||||
|
:param cid: User CID
|
||||||
|
:return: HTML template
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
user = requests.get(f"{VATSIM_API_URL}members/{cid}").json()
|
||||||
|
except requests.exceptions.JSONDecodeError:
|
||||||
|
raise HTTPException(404)
|
||||||
|
|
||||||
|
if "detail" in user and user["detail"] == "Not Found":
|
||||||
|
raise HTTPException(404)
|
||||||
|
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
name="viewer.html",
|
||||||
|
context={
|
||||||
|
"user": user,
|
||||||
|
"request": request,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.exception_handler(404)
|
||||||
|
async def error_handler(request: Request, _):
|
||||||
|
"""
|
||||||
|
Handler to the 404 HTTP error
|
||||||
|
|
||||||
|
:param request: FastAPI request
|
||||||
|
:return: HTML template
|
||||||
|
"""
|
||||||
|
|
||||||
|
return templates.TemplateResponse(
|
||||||
|
name="4O4.html",
|
||||||
|
context={
|
||||||
|
"request": request,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/api/request")
|
||||||
|
def request_handler(request_string: str):
|
||||||
|
"""
|
||||||
|
Wrapper to the VATSIM API functions
|
||||||
|
|
||||||
|
:param request_string: String that will fetched from VATSIM API
|
||||||
|
"""
|
||||||
|
|
||||||
|
if request_string:
|
||||||
try:
|
try:
|
||||||
return requests.get(f"{VATSIM_API_URL}{request_string}").json()
|
return requests.get(f"{VATSIM_API_URL}{request_string}").json()
|
||||||
except requests.exceptions.JSONDecodeError:
|
except requests.exceptions.JSONDecodeError:
|
||||||
return jsonify({"result": "error", "message": "Something went wrong. Report that error please"})
|
return {"result": "error", "message": "Something went wrong. Report that error please"}
|
||||||
|
|
||||||
return jsonify({"result": "not found", "message": "Not found"})
|
return {"result": "not found", "message": "Not found"}
|
||||||
|
|
||||||
|
|
||||||
@app.route("/<int:cid>/")
|
|
||||||
def viewer_page(cid):
|
|
||||||
user = requests.get(f"{VATSIM_API_URL}members/{cid}").json()
|
|
||||||
|
|
||||||
if "detail" in user and user["detail"] == "Not Found":
|
|
||||||
return abort(404)
|
|
||||||
|
|
||||||
return render_template("viewer.html", user=user)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
app.run(host="0.0.0.0", port=80)
|
uvicorn.run(app=app, host="0.0.0.0", port=80)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
Flask==2.2.5
|
fastapi==0.110.2
|
||||||
requests==2.31.0
|
requests==2.31.0
|
||||||
|
uvicorn==0.29.0
|
||||||
flake8==5.0.4
|
flake8==5.0.4
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<meta content="yes" name="apple-touch-fullscreen" />
|
<meta content="yes" name="apple-touch-fullscreen" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="#FA8232">
|
<meta name="apple-mobile-web-app-status-bar-style" content="#FA8232">
|
||||||
<meta name="format-detection" content="telephone=no">
|
<meta name="format-detection" content="telephone=no">
|
||||||
<link rel="icon" href="{{ url_for('static', filename='icon.ico') }}" type="image/x-icon">
|
<link rel="icon" href="{{ url_for('static', path='icon.ico') }}" type="image/x-icon">
|
||||||
<title>{% block title %}{% endblock %}</title>
|
<title>{% block title %}{% endblock %}</title>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
||||||
@@ -50,9 +50,7 @@
|
|||||||
<footer class="text-muted border-top">
|
<footer class="text-muted border-top">
|
||||||
<div class="container py-4">
|
<div class="container py-4">
|
||||||
created by
|
created by
|
||||||
<a href="https://uw935.t.me/" style="text-decoration: underline; cursor: pointer;">
|
<a href="https://uw935.com/" style="text-decoration: underline; cursor: pointer;">uw935</a> (1606255)
|
||||||
uw935
|
|
||||||
</a> (1606255)
|
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{% extends "/include/template.html" %}
|
{% extends "/include/template.html" %}
|
||||||
{% block title %}User {{user["id"]}} statistic — VATSIM Fox{% endblock %}
|
{% block title %}User {{user["id"]}} statistic — VATSIM Fox{% endblock %}
|
||||||
{% block header_css %}
|
{% block header_css %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='viewer.css') }}">
|
<link rel="stylesheet" href="{{ url_for('static', path='viewer.css') }}">
|
||||||
<link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet"/>
|
<link href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" rel="stylesheet"/>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
@@ -146,5 +146,5 @@
|
|||||||
|
|
||||||
$(".date_registration").text("{{user['reg_date']}}".replace("T", " "));
|
$(".date_registration").text("{{user['reg_date']}}".replace("T", " "));
|
||||||
</script>
|
</script>
|
||||||
<script type="text/javascript" src="{{ url_for('static', filename='viewer.js') }}"></script>
|
<script type="text/javascript" src="{{ url_for('static', path='viewer.js') }}"></script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
Reference in New Issue
Block a user