|
1 | 1 | """Generate CQL2 filter expressions via Jinja2 templating.""" |
2 | 2 |
|
3 | | -from dataclasses import dataclass, field |
4 | | -from typing import Any, Callable |
| 3 | +from typing import Any, Annotated, Callable |
5 | 4 |
|
6 | 5 | from cql2 import Expr |
7 | 6 | from fastapi import Request, Security |
|
10 | 9 | from ..utils import extract_variables |
11 | 10 |
|
12 | 11 |
|
13 | | -@dataclass |
14 | | -class Template: |
| 12 | +def Template(template_str: str, token_dependency: Callable[..., Any]): |
15 | 13 | """Generate CQL2 filter expressions via Jinja2 templating.""" |
16 | | - |
17 | | - template_str: str |
18 | | - token_dependency: Callable[..., Any] |
19 | | - |
20 | | - # Generated attributes |
21 | | - env: Environment = field(init=False) |
22 | | - dependency: Callable[[Request, Security], Expr] = field(init=False) |
23 | | - |
24 | | - def __post_init__(self): |
25 | | - """Initialize the Jinja2 environment.""" |
26 | | - self.env = Environment(loader=BaseLoader).from_string(self.template_str) |
27 | | - self.dependency = self.build() |
28 | | - |
29 | | - def build(self): |
30 | | - """Generate a dependency for rendering a CQL2 filter expression.""" |
31 | | - |
32 | | - async def dependency( |
33 | | - request: Request, auth_token=Security(self.token_dependency) |
34 | | - ) -> Expr: |
35 | | - """Render a CQL2 filter expression with the request and auth token.""" |
36 | | - # TODO: How to handle the case where auth_token is null? |
37 | | - context = { |
38 | | - "req": { |
39 | | - "path": request.url.path, |
40 | | - "method": request.method, |
41 | | - "query_params": dict(request.query_params), |
42 | | - "path_params": extract_variables(request.url.path), |
43 | | - "headers": dict(request.headers), |
44 | | - "body": ( |
45 | | - await request.json() |
46 | | - if request.headers.get("content-type") == "application/json" |
47 | | - else (await request.body()).decode() |
48 | | - ), |
49 | | - }, |
50 | | - "token": auth_token, |
51 | | - } |
52 | | - cql2_str = self.env.render(**context) |
53 | | - cql2_expr = Expr(cql2_str) |
54 | | - cql2_expr.validate() |
55 | | - return cql2_expr |
56 | | - |
57 | | - return dependency |
| 14 | + env = Environment(loader=BaseLoader).from_string(template_str) |
| 15 | + |
| 16 | + async def dependency( |
| 17 | + request: Request, |
| 18 | + auth_token=Annotated[dict[str, Any], Security(token_dependency)], |
| 19 | + ) -> Expr: |
| 20 | + """Render a CQL2 filter expression with the request and auth token.""" |
| 21 | + # TODO: How to handle the case where auth_token is null? |
| 22 | + context = { |
| 23 | + "req": { |
| 24 | + "path": request.url.path, |
| 25 | + "method": request.method, |
| 26 | + "query_params": dict(request.query_params), |
| 27 | + "path_params": extract_variables(request.url.path), |
| 28 | + "headers": dict(request.headers), |
| 29 | + "body": ( |
| 30 | + await request.json() |
| 31 | + if request.headers.get("content-type") == "application/json" |
| 32 | + else (await request.body()).decode() |
| 33 | + ), |
| 34 | + }, |
| 35 | + "token": auth_token, |
| 36 | + } |
| 37 | + cql2_str = env.render(**context) |
| 38 | + cql2_expr = Expr(cql2_str) |
| 39 | + cql2_expr.validate() |
| 40 | + return cql2_expr |
| 41 | + |
| 42 | + return dependency |
0 commit comments