57 lines
1.4 KiB
Python
57 lines
1.4 KiB
Python
|
from fastapi import FastAPI
|
||
|
from fastapi.responses import PlainTextResponse, JSONResponse
|
||
|
from fastapi.params import Query
|
||
|
import json
|
||
|
from pathlib import Path
|
||
|
|
||
|
app = FastAPI()
|
||
|
|
||
|
@app.get("/")
|
||
|
def lookup(
|
||
|
resource: str | None = None,
|
||
|
rel: list[str] = Query(None)
|
||
|
):
|
||
|
"""
|
||
|
Respond to a WebFinger query.
|
||
|
"""
|
||
|
|
||
|
# Basic info as a hint, if no resource given
|
||
|
if not resource:
|
||
|
return PlainTextResponse(
|
||
|
content="Query ?resource= for more information.",
|
||
|
status_code=400,
|
||
|
)
|
||
|
|
||
|
# otherwise, load that resource and return its data
|
||
|
filename = f"resource/{resource}.json"
|
||
|
path = Path(filename)
|
||
|
|
||
|
# TODO redirect to upstream webfinger server(s) if resource not found locally
|
||
|
# and if there is an upstream to try
|
||
|
if not path.is_file():
|
||
|
return PlainTextResponse(
|
||
|
content=f"{resource} not found",
|
||
|
status_code=404,
|
||
|
)
|
||
|
|
||
|
# open the local file
|
||
|
with open(filename, "r") as file:
|
||
|
data: dict = json.loads(file.read())
|
||
|
|
||
|
# filter links if rel is provided
|
||
|
links = [link for link in data.get('links')]
|
||
|
if rel:
|
||
|
links = [link for link in links if link.get('rel') in rel]
|
||
|
|
||
|
# construct json response
|
||
|
content = {
|
||
|
"subject": resource,
|
||
|
"aliases": [alias for alias in data.get('aliases')],
|
||
|
"properties": data.get('properties'),
|
||
|
"links": links,
|
||
|
}
|
||
|
content = {k: v for k, v in content.items() if v} # remove null values
|
||
|
headers = {
|
||
|
"Content-Type": "application/jrd+json"
|
||
|
}
|
||
|
return JSONResponse(content=content, headers=headers)
|