summaryrefslogtreecommitdiffstats
path: root/fatcat_scholar/web.py
blob: dfebe010c4442d594a0855c39baa60fd556a7f78 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

"""
This file is the FastAPI web application.
"""

from enum import Enum

from fastapi import FastAPI, APIRouter, Request, Depends
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse

I18N_LANG_DEFAULT = "en"
I18N_LANG_OPTIONS = ["en", "de", "zh"]

class LangPrefix:
    """
    Looks for a two-character language prefix.

    If there is no such prefix, in the future it could also look at the
    Accept-Language header and try to infer a language from that, while not
    setting the prefix code.
    """

    def __init__(self, request: Request):
        self.prefix : str = ""
        self.code : str = I18N_LANG_DEFAULT
        for lang_option in I18N_LANG_OPTIONS:
            if request.url.path.startswith(f"/{lang_option}/"):
                self.prefix = f"/{lang_option}"
                self.code = lang_option
                break

class ContentNegotiation:
    """
    Choses a mimetype to return based on Accept header.

    Intended to be used for RESTful content negotiation from web endpoints to API.
    """

    def __init__(self, request: Request):
        self.mimetype = "text/html"
        if request.headers.get('accept', '').startswith('application/json'):
            self.mimetype = "application/json"

api = APIRouter()

@api.get("/", operation_id="get_home")
async def home(request: Request):
    return {"endpoints": {"/": "this", "/search": "fulltext search"}}

@api.get("/search", operation_id="get_search")
async def search(request: Request):
    return {"message": "search results would go here, I guess"}

web = APIRouter()
templates = Jinja2Templates(directory="fatcat_scholar/templates")

@web.get("/", include_in_schema=False)
async def web_home(request: Request, lang: LangPrefix = Depends(LangPrefix), content: ContentNegotiation = Depends(ContentNegotiation)):
    if content.mimetype == "application/json":
        return await api_home(request)
    return templates.TemplateResponse("home.html", {"request": request})

@web.get("/search", include_in_schema=False)
async def web_search(request: Request):
    if content.mimetype == "application/json":
        return await api_search(request)
    return templates.TemplateResponse("search.html", {"request": request})

app = FastAPI()


app.include_router(web)
for lang_option in I18N_LANG_OPTIONS:
    app.include_router(web, prefix=f"/{lang_option}")
app.include_router(api)
app.mount("/static", StaticFiles(directory="fatcat_scholar/static"), name="static")