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 app = FastAPI() @app.get("/") def lookup( resource: str = Query(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 dir = env.get("RESOURCE_DIR") or "resource" filename = f"{dir}/{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) if __name__ == "__main__": import uvicorn uvicorn.run(app="webfinger:app", port=7033)