webfinger/webfinger/__init__.py

63 lines
1.6 KiB
Python
Raw Normal View History

2022-11-20 05:44:42 +00:00
from fastapi import FastAPI
from fastapi.responses import PlainTextResponse, JSONResponse
from fastapi.params import Query
import json
from pathlib import Path
from os import environ as env
2022-11-20 05:44:42 +00:00
app = FastAPI()
@app.get("/")
def lookup(
resource: str = Query(None),
2022-11-20 05:44:42 +00:00
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
dir = env.get("RESOURCE_DIR") or "resource"
filename = f"{dir}/{resource}.json"
2022-11-20 05:44:42 +00:00
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', [])]
2022-11-20 05:44:42 +00:00
if rel:
links = [link for link in links if link.get('rel', '') in rel]
2022-11-20 05:44:42 +00:00
# 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)
if __name__ == "__main__":
import uvicorn
uvicorn.run(app="webfinger:app", port=7033)