Skip to content

Commit

Permalink
[WEBHOOK]: Initial integration
Browse files Browse the repository at this point in the history
  • Loading branch information
amadolid committed Nov 26, 2024
1 parent 42d7b8e commit beeef27
Show file tree
Hide file tree
Showing 19 changed files with 759 additions and 138 deletions.
12 changes: 6 additions & 6 deletions jac-cloud/jac_cloud/core/architype.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,17 @@ def commit(session: ClientSession) -> None:
if ex.has_error_label("UnknownTransactionCommitResult"):
commit_retry += 1
logger.error(
"Error commiting bulk write! "
"Error commiting transaction! "
f"Retrying [{commit_retry}/{commit_max_retry}] ..."
)
continue
logger.error(
f"Error commiting bulk write after max retry [{commit_max_retry}] !"
f"Error commiting transaction after max retry [{commit_max_retry}] !"
)
raise
except Exception:
session.abort_transaction()
logger.error("Error commiting bulk write!")
logger.error("Error commiting transaction!")
raise

def execute(self, session: ClientSession) -> None:
Expand All @@ -250,16 +250,16 @@ def execute(self, session: ClientSession) -> None:
if ex.has_error_label("TransientTransactionError"):
transaction_retry += 1
logger.error(
"Error executing bulk write! "
"Error executing transaction! "
f"Retrying [{transaction_retry}/{transaction_max_retry}] ..."
)
continue
logger.error(
f"Error executing bulk write after max retry [{transaction_max_retry}] !"
f"Error executing transaction after max retry [{transaction_max_retry}] !"
)
raise
except Exception:
logger.error("Error executing bulk write!")
logger.error("Error executing transaction!")
raise


Expand Down
15 changes: 11 additions & 4 deletions jac-cloud/jac_cloud/jaseci/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,17 @@ async def lifespan(app: _FaststAPI) -> AsyncGenerator[None, _FaststAPI]:

populate_yaml_specs(cls.__app__)

from .routers import healthz_router, sso_router, user_router
from ..plugin.jaseci import walker_router

for router in [healthz_router, sso_router, user_router, walker_router]:
from .routers import healthz_router, sso_router, user_router, webhook_router
from ..plugin.jaseci import walker_router, webhook_walker_router

for router in [
healthz_router,
sso_router,
user_router,
webhook_router,
walker_router,
webhook_walker_router,
]:
cls.__app__.include_router(router)

@cls.__app__.exception_handler(Exception)
Expand Down
18 changes: 14 additions & 4 deletions jac-cloud/jac_cloud/jaseci/datasources/redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def keys(cls) -> list[bytes]:
return []

@classmethod
def set(cls, key: str, data: dict | bool) -> bool:
def set(cls, key: str, data: dict | bool | float) -> bool:
"""Push key value pair."""
try:
redis = cls.get_rd()
Expand Down Expand Up @@ -115,7 +115,7 @@ def hkeys(cls) -> list[str]:
return []

@classmethod
def hset(cls, key: str, data: dict | bool) -> bool:
def hset(cls, key: str, data: dict | bool | float) -> bool:
"""Push key value pair to group."""
try:
redis = cls.get_rd()
Expand Down Expand Up @@ -169,6 +169,16 @@ class TokenRedis(Redis):
__table__ = "token"


class WebhookRedis(Redis):
"""Token Memory Interface.
This interface is for Token Management.
You may override this if you wish to implement different structure
"""

__table__ = "webhook"


class AsyncRedis:
"""
Base Memory interface.
Expand Down Expand Up @@ -225,7 +235,7 @@ async def keys(cls) -> list[bytes]:
return []

@classmethod
async def set(cls, key: str, data: dict | bool) -> bool:
async def set(cls, key: str, data: dict | bool | float) -> bool:
"""Push key value pair."""
try:
redis = cls.get_rd()
Expand Down Expand Up @@ -266,7 +276,7 @@ async def hkeys(cls) -> list[str]:
return []

@classmethod
async def hset(cls, key: str, data: dict | bool) -> bool:
async def hset(cls, key: str, data: dict | bool | float) -> bool:
"""Push key value pair to group."""
try:
redis = cls.get_rd()
Expand Down
4 changes: 4 additions & 0 deletions jac-cloud/jac_cloud/jaseci/dtos/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
UserResetPassword,
UserVerification,
)
from .webhook import Expiration, GenerateKey, KeyIDs


__all__ = [
Expand All @@ -18,4 +19,7 @@
"UserRequest",
"UserResetPassword",
"UserVerification",
"Expiration",
"GenerateKey",
"KeyIDs",
]
31 changes: 31 additions & 0 deletions jac-cloud/jac_cloud/jaseci/dtos/webhook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
"""Jaseci User DTOs."""

from typing import Literal

from annotated_types import Len

from pydantic import BaseModel, Field, StringConstraints

from typing_extensions import Annotated


class Expiration(BaseModel):
"""Key Expiration."""

count: Annotated[int, Field(strict=True, gt=0, default=60)] = 60
interval: Literal["seconds", "minutes", "hours", "days"] = "days"


class GenerateKey(BaseModel):
"""User Creation Request Model."""

name: Annotated[str, StringConstraints(min_length=1)]
walkers: list[str] = Field(default_factory=list)
nodes: list[str] = Field(default_factory=list)
expiration: Expiration = Field(default_factory=Expiration)


class KeyIDs(BaseModel):
"""User Creation Request Model."""

ids: Annotated[list[str], Len(min_length=1)]
3 changes: 2 additions & 1 deletion jac-cloud/jac_cloud/jaseci/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"""Jaseci Models."""

from .user import NO_PASSWORD, User
from .webhook import Webhook

__all__ = ["NO_PASSWORD", "User"]
__all__ = ["NO_PASSWORD", "User", "Webhook"]
63 changes: 63 additions & 0 deletions jac-cloud/jac_cloud/jaseci/models/webhook.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""Jaseci Models."""

from dataclasses import asdict, dataclass, field
from datetime import datetime
from typing import Any, Generator, Mapping, cast

from bson import ObjectId

from ..datasources.collection import Collection as BaseCollection


@dataclass(kw_only=True)
class Webhook:
"""User Base Model."""

id: ObjectId = field(default_factory=ObjectId)
name: str
root_id: ObjectId
walkers: list[str]
nodes: list[str]
expiration: datetime
key: str

class Collection(BaseCollection["Webhook"]):
"""
User collection interface.
This interface is for User's Management.
You may override this if you wish to implement different structure
"""

__collection__ = "webhook"
__indexes__ = [
{"keys": ["name"], "unique": True},
{"keys": ["key"], "unique": True},
]

@classmethod
def __document__(cls, doc: Mapping[str, Any]) -> "Webhook":
"""
Return parsed Webhook from document.
This the default User parser after getting a single document.
You may override this to specify how/which class it will be casted/based.
"""
doc = cast(dict, doc)
return Webhook(id=doc.pop("_id"), **doc)

@classmethod
def find_by_root_id(cls, root_id: ObjectId) -> Generator["Webhook", None, None]:
"""Retrieve webhook via root_id."""
return cls.find({"root_id": root_id})

@classmethod
def find_by_key(cls, key: str) -> "Webhook | None":
"""Retrieve webhook via root_id."""
return cls.find_one({"key": key})

def __serialize__(self) -> dict:
"""Return serializable."""
data = asdict(self)
data["_id"] = data.pop("id")
return data
3 changes: 2 additions & 1 deletion jac-cloud/jac_cloud/jaseci/routers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@
from .healthz import router as healthz_router
from .sso import router as sso_router
from .user import router as user_router
from .webhook import router as webhook_router

__all__ = ["healthz_router", "sso_router", "user_router"]
__all__ = ["healthz_router", "sso_router", "user_router", "webhook_router"]
6 changes: 3 additions & 3 deletions jac-cloud/jac_cloud/jaseci/routers/sso.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,15 @@ def register(platform: str, open_id: OpenID) -> Response:
if ex.has_error_label("TransientTransactionError"):
retry += 1
logger.error(
"Error executing bulk write! "
"Error executing transaction! "
f"Retrying [{retry}/{max_retry}] ..."
)
continue
logger.exception("Error executing bulk write!")
logger.exception("Error executing transaction!")
session.abort_transaction()
break
except Exception:
logger.exception("Error executing bulk write!")
logger.exception("Error executing transaction!")
session.abort_transaction()
break
return ORJSONResponse({"message": "Registration Failed!"}, 409)
Expand Down
6 changes: 3 additions & 3 deletions jac-cloud/jac_cloud/jaseci/routers/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ def register(req: User.register_type()) -> ORJSONResponse: # type: ignore
if ex.has_error_label("TransientTransactionError"):
retry += 1
logger.error(
"Error executing bulk write! "
"Error executing transaction! "
f"Retrying [{retry}/{max_retry}] ..."
)
continue
logger.exception("Error executing bulk write!")
logger.exception("Error executing transaction!")
session.abort_transaction()
break
except Exception:
logger.exception("Error executing bulk write!")
logger.exception("Error executing transaction!")
session.abort_transaction()
break

Expand Down
Loading

0 comments on commit beeef27

Please sign in to comment.