Skip to content

Commit 9a9b9b8

Browse files
committed
Add OpaClient to wrap OPA interactions
1 parent 0e68df4 commit 9a9b9b8

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import logging
2+
from collections.abc import Mapping
3+
from contextlib import AbstractAsyncContextManager, aclosing, nullcontext
4+
from typing import Any, Self
5+
6+
import aiohttp
7+
from aiohttp import ClientSession
8+
9+
from blueapi.config import OpaConfig
10+
11+
LOGGER = logging.getLogger(__name__)
12+
13+
14+
class OpaClient:
15+
client: aiohttp.ClientSession
16+
17+
def __init__(self, instrument: str, config: OpaConfig):
18+
LOGGER.info("Creating OpaClient for %s with config %s", instrument, config)
19+
self._instrument = instrument
20+
self._conf = config
21+
self._session = ClientSession(base_url=config.root.encoded_string())
22+
23+
async def aclose(self):
24+
LOGGER.info("Closing OPA session")
25+
await self._session.close()
26+
27+
async def _call_opa(self, endpoint, data: Mapping[str, Any]) -> bool:
28+
try:
29+
resp = await self._session.post(
30+
endpoint,
31+
json={
32+
"input": {
33+
"beamline": self._instrument,
34+
"audience": "account",
35+
**data,
36+
}
37+
},
38+
)
39+
return (await resp.json())["result"]
40+
except Exception:
41+
LOGGER.exception("Failed to run check", exc_info=True)
42+
raise
43+
44+
@classmethod
45+
def for_config(
46+
cls, instrument: str, config: OpaConfig | None
47+
) -> AbstractAsyncContextManager[Self | None]:
48+
if config:
49+
return aclosing(cls(instrument, config))
50+
LOGGER.info("No OPA config provided - not creating OpaClient")
51+
return nullcontext()
52+
53+
54+
55+
class OpaUserClient:
56+
client: OpaClient
57+
token: str
58+
59+
def __init__(self, client: OpaClient, token: str):
60+
self.client = client
61+
self.token = token

0 commit comments

Comments
 (0)