Skip to content

Commit a040012

Browse files
committed
[WEBHOOK]: Initial integration
1 parent 83d192f commit a040012

File tree

19 files changed

+759
-136
lines changed

19 files changed

+759
-136
lines changed

jac-cloud/jac_cloud/core/architype.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -219,17 +219,17 @@ def commit(session: ClientSession) -> None:
219219
if ex.has_error_label("UnknownTransactionCommitResult"):
220220
commit_retry += 1
221221
logger.error(
222-
"Error commiting bulk write! "
222+
"Error commiting transaction! "
223223
f"Retrying [{commit_retry}/{commit_max_retry}] ..."
224224
)
225225
continue
226226
logger.error(
227-
f"Error commiting bulk write after max retry [{commit_max_retry}] !"
227+
f"Error commiting transaction after max retry [{commit_max_retry}] !"
228228
)
229229
raise
230230
except Exception:
231231
session.abort_transaction()
232-
logger.error("Error commiting bulk write!")
232+
logger.error("Error commiting transaction!")
233233
raise
234234

235235
def execute(self, session: ClientSession) -> None:
@@ -250,16 +250,16 @@ def execute(self, session: ClientSession) -> None:
250250
if ex.has_error_label("TransientTransactionError"):
251251
transaction_retry += 1
252252
logger.error(
253-
"Error executing bulk write! "
253+
"Error executing transaction! "
254254
f"Retrying [{transaction_retry}/{transaction_max_retry}] ..."
255255
)
256256
continue
257257
logger.error(
258-
f"Error executing bulk write after max retry [{transaction_max_retry}] !"
258+
f"Error executing transaction after max retry [{transaction_max_retry}] !"
259259
)
260260
raise
261261
except Exception:
262-
logger.error("Error executing bulk write!")
262+
logger.error("Error executing transaction!")
263263
raise
264264

265265

jac-cloud/jac_cloud/jaseci/__init__.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,17 @@ async def lifespan(app: _FaststAPI) -> AsyncGenerator[None, _FaststAPI]:
7070

7171
populate_yaml_specs(cls.__app__)
7272

73-
from .routers import healthz_router, sso_router, user_router
74-
from ..plugin.jaseci import walker_router
75-
76-
for router in [healthz_router, sso_router, user_router, walker_router]:
73+
from .routers import healthz_router, sso_router, user_router, webhook_router
74+
from ..plugin.jaseci import walker_router, webhook_walker_router
75+
76+
for router in [
77+
healthz_router,
78+
sso_router,
79+
user_router,
80+
webhook_router,
81+
walker_router,
82+
webhook_walker_router,
83+
]:
7784
cls.__app__.include_router(router)
7885

7986
@cls.__app__.exception_handler(Exception)

jac-cloud/jac_cloud/jaseci/datasources/redis.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def keys(cls) -> list[bytes]:
7474
return []
7575

7676
@classmethod
77-
def set(cls, key: str, data: dict | bool) -> bool:
77+
def set(cls, key: str, data: dict | bool | float) -> bool:
7878
"""Push key value pair."""
7979
try:
8080
redis = cls.get_rd()
@@ -115,7 +115,7 @@ def hkeys(cls) -> list[str]:
115115
return []
116116

117117
@classmethod
118-
def hset(cls, key: str, data: dict | bool) -> bool:
118+
def hset(cls, key: str, data: dict | bool | float) -> bool:
119119
"""Push key value pair to group."""
120120
try:
121121
redis = cls.get_rd()
@@ -169,6 +169,16 @@ class TokenRedis(Redis):
169169
__table__ = "token"
170170

171171

172+
class WebhookRedis(Redis):
173+
"""Token Memory Interface.
174+
175+
This interface is for Token Management.
176+
You may override this if you wish to implement different structure
177+
"""
178+
179+
__table__ = "webhook"
180+
181+
172182
class AsyncRedis:
173183
"""
174184
Base Memory interface.
@@ -225,7 +235,7 @@ async def keys(cls) -> list[bytes]:
225235
return []
226236

227237
@classmethod
228-
async def set(cls, key: str, data: dict | bool) -> bool:
238+
async def set(cls, key: str, data: dict | bool | float) -> bool:
229239
"""Push key value pair."""
230240
try:
231241
redis = cls.get_rd()
@@ -266,7 +276,7 @@ async def hkeys(cls) -> list[str]:
266276
return []
267277

268278
@classmethod
269-
async def hset(cls, key: str, data: dict | bool) -> bool:
279+
async def hset(cls, key: str, data: dict | bool | float) -> bool:
270280
"""Push key value pair to group."""
271281
try:
272282
redis = cls.get_rd()

jac-cloud/jac_cloud/jaseci/dtos/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
UserResetPassword,
99
UserVerification,
1010
)
11+
from .webhook import Expiration, GenerateKey, KeyIDs
1112

1213

1314
__all__ = [
@@ -18,4 +19,7 @@
1819
"UserRequest",
1920
"UserResetPassword",
2021
"UserVerification",
22+
"Expiration",
23+
"GenerateKey",
24+
"KeyIDs",
2125
]
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
"""Jaseci User DTOs."""
2+
3+
from typing import Literal
4+
5+
from annotated_types import Len
6+
7+
from pydantic import BaseModel, Field, StringConstraints
8+
9+
from typing_extensions import Annotated
10+
11+
12+
class Expiration(BaseModel):
13+
"""Key Expiration."""
14+
15+
count: Annotated[int, Field(strict=True, gt=0, default=60)] = 60
16+
interval: Literal["seconds", "minutes", "hours", "days"] = "days"
17+
18+
19+
class GenerateKey(BaseModel):
20+
"""User Creation Request Model."""
21+
22+
name: Annotated[str, StringConstraints(min_length=1)]
23+
walkers: list[str] = Field(default_factory=list)
24+
nodes: list[str] = Field(default_factory=list)
25+
expiration: Expiration = Field(default_factory=Expiration)
26+
27+
28+
class KeyIDs(BaseModel):
29+
"""User Creation Request Model."""
30+
31+
ids: Annotated[list[str], Len(min_length=1)]
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Jaseci Models."""
22

33
from .user import NO_PASSWORD, User
4+
from .webhook import Webhook
45

5-
__all__ = ["NO_PASSWORD", "User"]
6+
__all__ = ["NO_PASSWORD", "User", "Webhook"]
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
"""Jaseci Models."""
2+
3+
from dataclasses import asdict, dataclass, field
4+
from datetime import datetime
5+
from typing import Any, Generator, Mapping, cast
6+
7+
from bson import ObjectId
8+
9+
from ..datasources.collection import Collection as BaseCollection
10+
11+
12+
@dataclass(kw_only=True)
13+
class Webhook:
14+
"""User Base Model."""
15+
16+
id: ObjectId = field(default_factory=ObjectId)
17+
name: str
18+
root_id: ObjectId
19+
walkers: list[str]
20+
nodes: list[str]
21+
expiration: datetime
22+
key: str
23+
24+
class Collection(BaseCollection["Webhook"]):
25+
"""
26+
User collection interface.
27+
28+
This interface is for User's Management.
29+
You may override this if you wish to implement different structure
30+
"""
31+
32+
__collection__ = "webhook"
33+
__indexes__ = [
34+
{"keys": ["name"], "unique": True},
35+
{"keys": ["key"], "unique": True},
36+
]
37+
38+
@classmethod
39+
def __document__(cls, doc: Mapping[str, Any]) -> "Webhook":
40+
"""
41+
Return parsed Webhook from document.
42+
43+
This the default User parser after getting a single document.
44+
You may override this to specify how/which class it will be casted/based.
45+
"""
46+
doc = cast(dict, doc)
47+
return Webhook(id=doc.pop("_id"), **doc)
48+
49+
@classmethod
50+
def find_by_root_id(cls, root_id: ObjectId) -> Generator["Webhook", None, None]:
51+
"""Retrieve webhook via root_id."""
52+
return cls.find({"root_id": root_id})
53+
54+
@classmethod
55+
def find_by_key(cls, key: str) -> "Webhook | None":
56+
"""Retrieve webhook via root_id."""
57+
return cls.find_one({"key": key})
58+
59+
def __serialize__(self) -> dict:
60+
"""Return serializable."""
61+
data = asdict(self)
62+
data["_id"] = data.pop("id")
63+
return data

jac-cloud/jac_cloud/jaseci/routers/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
from .healthz import router as healthz_router
44
from .sso import router as sso_router
55
from .user import router as user_router
6+
from .webhook import router as webhook_router
67

7-
__all__ = ["healthz_router", "sso_router", "user_router"]
8+
__all__ = ["healthz_router", "sso_router", "user_router", "webhook_router"]

jac-cloud/jac_cloud/jaseci/routers/sso.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -245,15 +245,15 @@ def register(platform: str, open_id: OpenID) -> Response:
245245
if ex.has_error_label("TransientTransactionError"):
246246
retry += 1
247247
logger.error(
248-
"Error executing bulk write! "
248+
"Error executing transaction! "
249249
f"Retrying [{retry}/{max_retry}] ..."
250250
)
251251
continue
252-
logger.exception("Error executing bulk write!")
252+
logger.exception("Error executing transaction!")
253253
session.abort_transaction()
254254
break
255255
except Exception:
256-
logger.exception("Error executing bulk write!")
256+
logger.exception("Error executing transaction!")
257257
session.abort_transaction()
258258
break
259259
return ORJSONResponse({"message": "Registration Failed!"}, 409)

jac-cloud/jac_cloud/jaseci/routers/user.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,15 @@ def register(req: User.register_type()) -> ORJSONResponse: # type: ignore
6666
if ex.has_error_label("TransientTransactionError"):
6767
retry += 1
6868
logger.error(
69-
"Error executing bulk write! "
69+
"Error executing transaction! "
7070
f"Retrying [{retry}/{max_retry}] ..."
7171
)
7272
continue
73-
logger.exception("Error executing bulk write!")
73+
logger.exception("Error executing transaction!")
7474
session.abort_transaction()
7575
break
7676
except Exception:
77-
logger.exception("Error executing bulk write!")
77+
logger.exception("Error executing transaction!")
7878
session.abort_transaction()
7979
break
8080

0 commit comments

Comments
 (0)