|
| 1 | +from typing import Any, Callable |
| 2 | + |
| 3 | +from cql2 import Expr |
| 4 | +from jinja2 import Environment, BaseLoader |
| 5 | +from fastapi import Request, Security |
| 6 | + |
| 7 | +from ..utils import extract_variables |
| 8 | + |
| 9 | +from dataclasses import dataclass, field |
| 10 | + |
| 11 | + |
| 12 | +@dataclass |
| 13 | +class Template: |
| 14 | + template_str: str |
| 15 | + token_dependency: Callable[..., Any] |
| 16 | + |
| 17 | + # Generated attributes |
| 18 | + env: Environment = field(init=False) |
| 19 | + |
| 20 | + def __post_init__(self): |
| 21 | + self.env = Environment(loader=BaseLoader).from_string(self.template_str) |
| 22 | + self.render.__annotations__["auth_token"] = Security(self.token_dependency) |
| 23 | + |
| 24 | + async def cql2(self, request: Request, auth_token=Security(...)) -> Expr: |
| 25 | + # TODO: How to handle the case where auth_token is null? |
| 26 | + context = { |
| 27 | + "req": { |
| 28 | + "path": request.url.path, |
| 29 | + "method": request.method, |
| 30 | + "query_params": dict(request.query_params), |
| 31 | + "path_params": extract_variables(request.url.path), |
| 32 | + "headers": dict(request.headers), |
| 33 | + "body": ( |
| 34 | + await request.json() |
| 35 | + if request.headers.get("content-type") == "application/json" |
| 36 | + else (await request.body()).decode() |
| 37 | + ), |
| 38 | + }, |
| 39 | + "token": auth_token, |
| 40 | + } |
| 41 | + cql2_str = self.env.render(**context) |
| 42 | + cql2_expr = Expr(cql2_str) |
| 43 | + cql2_expr.validate() |
| 44 | + return cql2_expr |
0 commit comments