diff --git a/cybsi/cloud/auth/__init__.py b/cybsi/cloud/auth/__init__.py index 3bf45c8..c944d26 100644 --- a/cybsi/cloud/auth/__init__.py +++ b/cybsi/cloud/auth/__init__.py @@ -8,6 +8,12 @@ APIKeyForm, APIKeyView, ) +from .limits import ( + RequestLimitForm, + RequestLimitTargetView, + RequestLimitView, + LimitPeriod, +) from .permission import ( ResourceAction, ResourcePermissionView, diff --git a/cybsi/cloud/auth/api_key.py b/cybsi/cloud/auth/api_key.py index 1da14fe..b8e1e2f 100644 --- a/cybsi/cloud/auth/api_key.py +++ b/cybsi/cloud/auth/api_key.py @@ -18,6 +18,7 @@ rfc3339_timestamp, ) from ..pagination import Cursor, Page +from .limits import RequestLimitForm, RequestLimitView from .permission import ResourcePermissionForm, ResourcePermissionView from .token import TokenView @@ -196,12 +197,14 @@ class APIKeyForm(JsonObjectForm): expires_at: Expiration date. The API-Key is automatically disabled after the expiration date. description: API-Key description. + request_limits: List of API-Key request limits. """ def __init__( self, permissions: Iterable[ResourcePermissionForm], *, + request_limits: Optional[Iterable[RequestLimitForm]] = None, expires_at: Optional[datetime] = None, description: Optional[str] = None, ): @@ -210,6 +213,8 @@ def __init__( self._data["expiresAt"] = rfc3339_timestamp(expires_at) if description is not None: self._data["description"] = description + if request_limits is not None: + self._data["requestLimits"] = [limit.json() for limit in request_limits] self._data["permissions"] = [perm.json() for perm in permissions] @@ -268,3 +273,8 @@ def revoked(self) -> bool: def permissions(self) -> List[ResourcePermissionView]: """List of permissions.""" return [ResourcePermissionView(perm) for perm in self._get("permissions")] + + @property + def request_limits(self) -> List[RequestLimitView]: + """List of request limits.""" + return [RequestLimitView(limit) for limit in self._get("requestLimits")] diff --git a/cybsi/cloud/auth/limits.py b/cybsi/cloud/auth/limits.py new file mode 100644 index 0000000..b9204aa --- /dev/null +++ b/cybsi/cloud/auth/limits.py @@ -0,0 +1,71 @@ +from enum_tools import document_enum + +from ..enum import CybsiAPIEnum +from ..internal import JsonObjectForm, JsonObjectView +from .permission import ResourceAction +from .resource import ResourceRefView + + +@document_enum +class LimitPeriod(CybsiAPIEnum): + """Limit time window.""" + + Day = "Day" + """Time window with period of one day.""" + + +class RequestLimitTargetView(JsonObjectView): + """Request limit target.""" + + @property + def resource(self) -> ResourceRefView: + """Resource.""" + return ResourceRefView(self._get("resource")) + + @property + def action(self) -> ResourceAction: + """Limited action.""" + return ResourceAction(self._get("action")) + + +class RequestLimitView(JsonObjectView): + """Request limit.""" + + @property + def target(self) -> RequestLimitTargetView: + """Limit target.""" + return RequestLimitTargetView(self._get("target")) + + @property + def limit(self) -> int: + """Maximum requests count within time window.""" + return self._get("limit") + + @property + def period(self) -> LimitPeriod: + """Time window for limit.""" + return LimitPeriod(self._get("period")) + + +class RequestLimitForm(JsonObjectForm): + """Request limit form. + + Args: + resource_id: resource identifier. + action: limited action. + limit_period: time window for limit. + limit: maximum requests count within time window. + """ + + def __init__( + self, + *, + resource_id: int, + action: ResourceAction, + limit_period: LimitPeriod, + limit: int, + ): + super().__init__() + self._data["target"] = {"resource": {"id": resource_id}, "action": action.value} + self._data["limit"] = limit + self._data["period"] = limit_period.value diff --git a/cybsi/cloud/error.py b/cybsi/cloud/error.py index 882ba4b..8b4a974 100644 --- a/cybsi/cloud/error.py +++ b/cybsi/cloud/error.py @@ -199,6 +199,10 @@ class SemanticErrorCodes(CybsiAPIEnum): """schemaID parameter can't be changed.""" SchemaNotFound = "SchemaNotFound" """The specified schema is not found""" + InvalidRequestLimit = "InvalidRequestLimit" + """The specified request limit cannot be set.""" + LimitSetConflict = "LimitSetConflict" + """The limit set has conflicts.""" # Objects InvalidKeyFormat = "InvalidKeyFormat" diff --git a/examples/get_collection_objects_chained.py b/examples/get_collection_objects_chained.py index 75d06b1..f3b488c 100644 --- a/examples/get_collection_objects_chained.py +++ b/examples/get_collection_objects_chained.py @@ -10,8 +10,7 @@ # Retrieve collection schema, it describes all attributes # of objects you can encounter in the collection. - schema_view = client.iocean.collections.view_schema( - collection_id=collection_id) + schema_view = client.iocean.collections.view_schema(collection_id=collection_id) print(schema_view.schema) # Retrieve first page of collection objects.