From 793938ca1d470697957cf2af58533485d10fefc7 Mon Sep 17 00:00:00 2001 From: Aashish Bhandari Date: Thu, 23 Feb 2023 13:02:26 +0545 Subject: [PATCH 1/4] Removed generated schema --- .../client/async_base_client.py | 70 +++ .../rest_api_client/client/async_client.py | 348 ++++++++++++++ .../client/async_connectors_client.py | 437 ++++++++++++++++++ .../client/async_platform_client.py | 38 ++ 4 files changed, 893 insertions(+) create mode 100644 authomize/rest_api_client/client/async_base_client.py create mode 100644 authomize/rest_api_client/client/async_client.py create mode 100644 authomize/rest_api_client/client/async_connectors_client.py create mode 100644 authomize/rest_api_client/client/async_platform_client.py diff --git a/authomize/rest_api_client/client/async_base_client.py b/authomize/rest_api_client/client/async_base_client.py new file mode 100644 index 0000000..806a3f9 --- /dev/null +++ b/authomize/rest_api_client/client/async_base_client.py @@ -0,0 +1,70 @@ +from typing import Optional + +import aiohttp +from aiohttp import ClientResponse + +AUTHOMIZE_API_URL = 'https://api.authomize.com' +STATUS_OK: int = 200 + + +class AsyncClientError(Exception): + def __init__(self, message): + self.message = message + + +class AsyncBaseClient: + def __init__(self, auth_token: str, base_url: str = AUTHOMIZE_API_URL): + self.auth_token = auth_token + self.base_url = base_url + self.session = aiohttp.ClientSession() + self.session.headers.update({'Authorization': self.authorization_header}) + + @property + def authorization_header(self) -> str: + raise NotImplementedError() + + async def http_get(self, url, params=None): + url = self.base_url + url + response: ClientResponse = await self.session.get(url, params=params) + if response.status == STATUS_OK: + return response.json() + try: + response_json = await response.json() + detail = response_json.get('detail') + except Exception: + detail = None + if detail: + raise AsyncClientError(str(detail)) + response.raise_for_status() + + async def http_post(self, url: str, body: Optional[str] = None): + url = self.base_url + url + response = await self.session.post( + url, + headers={'Content-Type': 'application/json'}, + data=body, + ) + if response.status == STATUS_OK: + return await response.json() + try: + response_json = await response.json() + detail = response_json.get('detail') + except Exception: + detail = None + if detail: + raise AsyncClientError(str(detail)) + response.raise_for_status() + + async def http_delete(self, url: str, params=None): + url = self.base_url + url + response = await self.session.delete(url, params=params) + if response.status == STATUS_OK: + return await response.json() + try: + response_json = await response.json() + detail = response_json.get('detail') + except Exception: + detail = None + if detail: + raise AsyncClientError(str(detail)) + response.raise_for_status() diff --git a/authomize/rest_api_client/client/async_client.py b/authomize/rest_api_client/client/async_client.py new file mode 100644 index 0000000..79f83fd --- /dev/null +++ b/authomize/rest_api_client/client/async_client.py @@ -0,0 +1,348 @@ +from datetime import datetime +from typing import Optional + +from apiclient_pydantic import serialize_all_methods, serialize_response + +from authomize.rest_api_client.client.async_connectors_client import AsyncConnectorsClient +from authomize.rest_api_client.client.async_platform_client import AsyncPlatformClient +from authomize.rest_api_client.client.base_client import AUTHOMIZE_API_URL +from authomize.rest_api_client.generated.connectors_rest_api.schemas import ( + BundleTransactionSchema, + ItemsBundleSchema, + NewAccountsAssociationResponseSchema, + NewAccountsAssociationsListRequestSchema, + NewAssetsInheritanceListRequestSchema, + NewAssetsInheritanceResponseSchema, + NewAssetsListRequestSchema, + NewAssetsResponseSchema, + NewGroupingResponseSchema, + NewGroupingsAssociationResponseSchema, + NewGroupingsAssociationsListRequestSchema, + NewGroupingsListRequestSchema, + NewIdentitiesListRequestSchema, + NewIdentityResponseSchema, + NewPermissionsListRequestSchema, + NewPermissionsResponseSchema, + NewPrivilegeGrantsResponseSchema, + NewPrivilegesGrantsListRequestSchema, + NewPrivilegesListRequestSchema, + NewPrivilegesResponseSchema, + NewUserResponseSchema, + NewUsersListRequestSchema, + RestApiConnectorListSchema, + SearchAccountsAssociationsListResponseSchema, + SearchAssetsInheritanceListResponseSchema, + SearchAssetsListResponseSchema, + SearchGroupingResponseSchema, + SearchGroupingsAssociationsListResponseSchema, + SearchIdentitiesListResponseSchema, + SearchPermissionResponseSchema, + SearchPrivilegeGrantsListResponseSchema, + SearchPrivilegesListResponseSchema, + SearchUsersListResponseSchema, + SubmitResponse, +) +from authomize.rest_api_client.generated.external_rest_api.schemas import ( + IncidentExpansion, + IsAliveResponse, + MeResponse, +) + + +@serialize_all_methods(decorator=serialize_response) +class AsyncClient: + def __init__( + self, + *args, + auth_token: str, + base_url: str = AUTHOMIZE_API_URL, + **kwargs, + ): + self.auth_token = auth_token + self.base_url = base_url + self.connectors_client = AsyncConnectorsClient( + *args, + auth_token=auth_token, + base_url=base_url, + **kwargs, + ) + self.platform_client = AsyncPlatformClient( + *args, + auth_token=auth_token, + base_url=base_url, + **kwargs, + ) + + async def is_alive(self) -> IsAliveResponse: + return await self.platform_client.is_alive() + + async def me(self) -> MeResponse: + return await self.platform_client.me() + + async def list_connectors( + self, + params=None, + ) -> RestApiConnectorListSchema: + return await self.connectors_client.list_connectors( + params=params, + ) + + async def create_transaction( + self, + connector_id: str, + ) -> BundleTransactionSchema: + return await self.connectors_client.create_transaction( + connector_id=connector_id, + ) + + async def retrieve_transaction( + self, + connector_id: str, + transaction_id: str, + ) -> BundleTransactionSchema: + return await self.connectors_client.retrieve_transaction( + connector_id=connector_id, + transaction_id=transaction_id, + ) + + async def apply_transaction( + self, + connector_id: str, + transaction_id: str, + ) -> BundleTransactionSchema: + return await self.connectors_client.apply_transaction( + connector_id=connector_id, + transaction_id=transaction_id, + ) + + async def extend_transaction_items( + self, + connector_id: str, + transaction_id: str, + items: ItemsBundleSchema, + ) -> SubmitResponse: + return await self.connectors_client.extend_transaction_items( + connector_id=connector_id, + transaction_id=transaction_id, + items=items, + ) + + async def delete_app_data( + self, + app_id: str, + modified_before: Optional[datetime] = None, + ) -> SubmitResponse: + return await self.connectors_client.delete_app_data( + app_id=app_id, + modified_before=modified_before, + ) + + async def search_users( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchUsersListResponseSchema: + return await self.connectors_client.search_users( + app_id=app_id, + start_date=start_date, + ) + + async def create_users( + self, + app_id: str, + body: NewUsersListRequestSchema, + ) -> NewUserResponseSchema: + return await self.connectors_client.create_users( + app_id=app_id, + body=body, + ) + + async def search_groupings( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchGroupingResponseSchema: + return await self.connectors_client.search_groupings( + app_id=app_id, + start_date=start_date, + ) + + async def create_groupings( + self, + app_id: str, + body: NewGroupingsListRequestSchema, + ) -> NewGroupingResponseSchema: + return await self.connectors_client.create_groupings( + app_id=app_id, + body=body, + ) + + async def search_permissions( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchPermissionResponseSchema: + return await self.connectors_client.search_permissions( + app_id=app_id, + start_date=start_date, + ) + + async def create_permissions( + self, + app_id: str, + body: NewPermissionsListRequestSchema, + ) -> NewPermissionsResponseSchema: + return await self.connectors_client.create_permissions( + app_id=app_id, + body=body, + ) + + async def search_privileges( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchPrivilegesListResponseSchema: + return await self.connectors_client.search_privileges( + app_id=app_id, + start_date=start_date, + ) + + async def create_privileges( + self, + app_id: str, + body: NewPrivilegesListRequestSchema, + ) -> NewPrivilegesResponseSchema: + return await self.connectors_client.create_privileges( + app_id=app_id, + body=body, + ) + + async def search_privileges_grants( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchPrivilegeGrantsListResponseSchema: + return await self.connectors_client.search_privileges_grants( + app_id=app_id, + start_date=start_date, + ) + + async def create_privileges_grants( + self, + app_id: str, + body: NewPrivilegesGrantsListRequestSchema, + ) -> NewPrivilegeGrantsResponseSchema: + return await self.connectors_client.create_privileges_grants( + app_id=app_id, + body=body, + ) + + async def search_accounts_association( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchAccountsAssociationsListResponseSchema: + return await self.connectors_client.search_accounts_association( + app_id=app_id, + start_date=start_date, + ) + + async def create_accounts_association( + self, + app_id: str, + body: NewAccountsAssociationsListRequestSchema, + ) -> NewAccountsAssociationResponseSchema: + return await self.connectors_client.create_accounts_association( + app_id=app_id, + body=body, + ) + + async def search_groupings_association( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchGroupingsAssociationsListResponseSchema: + return await self.connectors_client.search_groupings_association( + app_id=app_id, + start_date=start_date, + ) + + async def create_groupings_association( + self, + app_id: str, + body: NewGroupingsAssociationsListRequestSchema, + ) -> NewGroupingsAssociationResponseSchema: + return await self.connectors_client.create_groupings_association( + app_id=app_id, + body=body, + ) + + async def search_assets( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchAssetsListResponseSchema: + return await self.connectors_client.search_assets( + app_id=app_id, + start_date=start_date, + ) + + async def create_assets( + self, + app_id: str, + body: NewAssetsListRequestSchema, + ) -> NewAssetsResponseSchema: + return await self.connectors_client.create_assets( + app_id=app_id, + body=body, + ) + + async def search_assets_inheritance( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchAssetsInheritanceListResponseSchema: + return await self.connectors_client.search_assets_inheritance( + app_id=app_id, + start_date=start_date, + ) + + async def create_assets_inheritance( + self, + app_id: str, + body: NewAssetsInheritanceListRequestSchema, + ) -> NewAssetsInheritanceResponseSchema: + return await self.connectors_client.create_assets_inheritance( + app_id=app_id, + body=body, + ) + + async def search_identities( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchIdentitiesListResponseSchema: + return await self.connectors_client.search_identities( + app_id=app_id, + start_date=start_date, + ) + + async def create_identities( + self, + app_id: str, + body: NewIdentitiesListRequestSchema, + ) -> NewIdentityResponseSchema: + return await self.connectors_client.create_identities( + app_id=app_id, + body=body, + ) + + async def retrieve_incident( + self, + incident_id: str, + expand: Optional[list[IncidentExpansion]] = None, + ): + return self.platform_client.retrieve_incident( + incident_id=incident_id, + expand=expand, + ) diff --git a/authomize/rest_api_client/client/async_connectors_client.py b/authomize/rest_api_client/client/async_connectors_client.py new file mode 100644 index 0000000..ee80ba8 --- /dev/null +++ b/authomize/rest_api_client/client/async_connectors_client.py @@ -0,0 +1,437 @@ +import json +from datetime import datetime +from typing import Optional + +from pydantic.json import pydantic_encoder + +from authomize.rest_api_client.client.async_base_client import AsyncBaseClient +from authomize.rest_api_client.generated.connectors_rest_api.schemas import ( + BundleTransactionSchema, + ItemsBundleSchema, + NewAccountsAssociationResponseSchema, + NewAccountsAssociationsListRequestSchema, + NewAssetsInheritanceListRequestSchema, + NewAssetsInheritanceResponseSchema, + NewAssetsListRequestSchema, + NewAssetsResponseSchema, + NewGroupingResponseSchema, + NewGroupingsAssociationResponseSchema, + NewGroupingsAssociationsListRequestSchema, + NewGroupingsListRequestSchema, + NewIdentitiesListRequestSchema, + NewIdentityResponseSchema, + NewPermissionsListRequestSchema, + NewPermissionsResponseSchema, + NewPrivilegeGrantsResponseSchema, + NewPrivilegesGrantsListRequestSchema, + NewPrivilegesListRequestSchema, + NewPrivilegesResponseSchema, + NewUserResponseSchema, + NewUsersListRequestSchema, + RestApiConnectorListSchema, + SearchAccountsAssociationsListResponseSchema, + SearchAssetsInheritanceListResponseSchema, + SearchAssetsListResponseSchema, + SearchGroupingResponseSchema, + SearchGroupingsAssociationsListResponseSchema, + SearchIdentitiesListResponseSchema, + SearchPermissionResponseSchema, + SearchPrivilegeGrantsListResponseSchema, + SearchPrivilegesListResponseSchema, + SearchUsersListResponseSchema, + SubmitResponse, +) + + +class AsyncConnectorsClient(AsyncBaseClient): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + @property + def authorization_header(self) -> str: + return self.auth_token + + async def list_connectors( + self, + params=None, + ) -> RestApiConnectorListSchema: + return await self.http_get('/v1/connectors', params=params) + + async def create_transaction( + self, + connector_id: str, + ) -> BundleTransactionSchema: + if not connector_id: + raise ValueError('Missing connector_id') + return await self.http_post(f'/v1/connectors/{connector_id}/transactions') + + async def retrieve_transaction( + self, + connector_id: str, + transaction_id: str, + ) -> BundleTransactionSchema: + if not connector_id: + raise ValueError('Missing connector_id') + if not transaction_id: + raise ValueError('Missing transaction_id') + return await self.http_get(f'/v1/connectors/{connector_id}/transactions/{transaction_id}') + + async def apply_transaction( + self, + connector_id: str, + transaction_id: str, + ) -> BundleTransactionSchema: + if not connector_id: + raise ValueError('Missing connector_id') + if not transaction_id: + raise ValueError('Missing transaction_id') + return await self.http_post( + f'/v1/connectors/{connector_id}/transactions/{transaction_id}/apply' + ) + + async def extend_transaction_items( + self, + connector_id: str, + transaction_id: str, + items: ItemsBundleSchema, + ) -> SubmitResponse: + if not connector_id: + raise ValueError('Missing connector_id') + if not transaction_id: + raise ValueError('Missing transaction_id') + return await self.http_post( + f'/v1/connectors/{connector_id}/transactions/{transaction_id}/items', + body=items.json(), + ) + + async def delete_app_data( + self, + app_id: str, + modified_before: Optional[datetime] = None, + ) -> SubmitResponse: + if not app_id: + raise ValueError('Missing app_id') + date_filter = '' + if modified_before: + date_filter = f'?modifiedBefore={str(modified_before)}' + return await self.http_delete(url=f"/v2/apps/{app_id}/data{date_filter}") + + async def search_users( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchUsersListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/accounts/users', + params={ + **params, + }, + ) + + async def create_users( + self, + app_id: str, + body: NewUsersListRequestSchema, + ) -> NewUserResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/accounts/users', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_groupings( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchGroupingResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/access/grouping', + params={ + **params, + }, + ) + + async def create_groupings( + self, + app_id: str, + body: NewGroupingsListRequestSchema, + ) -> NewGroupingResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/access/grouping', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_permissions( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchPermissionResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/access/permissions', + params={ + **params, + }, + ) + + async def create_permissions( + self, + app_id: str, + body: NewPermissionsListRequestSchema, + ) -> NewPermissionsResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/access/permissions', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_privileges( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchPrivilegesListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/privileges', + params={ + **params, + }, + ) + + async def create_privileges( + self, + app_id: str, + body: NewPrivilegesListRequestSchema, + ) -> NewPrivilegesResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/privileges', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_privileges_grants( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchPrivilegeGrantsListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/privileges/grants', + params={ + **params, + }, + ) + + async def create_privileges_grants( + self, + app_id: str, + body: NewPrivilegesGrantsListRequestSchema, + ) -> NewPrivilegeGrantsResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/privileges/grants', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_accounts_association( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchAccountsAssociationsListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/association/accounts', + params={ + **params, + }, + ) + + async def create_accounts_association( + self, + app_id: str, + body: NewAccountsAssociationsListRequestSchema, + ) -> NewAccountsAssociationResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/association/accounts', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_groupings_association( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchGroupingsAssociationsListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/association/groupings', + params={ + **params, + }, + ) + + async def create_groupings_association( + self, + app_id: str, + body: NewGroupingsAssociationsListRequestSchema, + ) -> NewGroupingsAssociationResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/association/groupings', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_assets( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchAssetsListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/assets', + params={ + **params, + }, + ) + + async def create_assets( + self, + app_id: str, + body: NewAssetsListRequestSchema, + ) -> NewAssetsResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/assets', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_assets_inheritance( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchAssetsInheritanceListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/assets/inheritance', + params={ + **params, + }, + ) + + async def create_assets_inheritance( + self, + app_id: str, + body: NewAssetsInheritanceListRequestSchema, + ) -> NewAssetsInheritanceResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/assets/inheritance', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) + + async def search_identities( + self, + app_id: str, + start_date: Optional[datetime] = None, + ) -> SearchIdentitiesListResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + params = dict( + start_date=start_date, + ) + return await self.http_get( + url=f'/v2/apps/{app_id}/identities', + params={ + **params, + }, + ) + + async def create_identities( + self, + app_id: str, + body: NewIdentitiesListRequestSchema, + ) -> NewIdentityResponseSchema: + if not app_id: + raise ValueError('Missing app_id') + return await self.http_post( + url=f'/v2/apps/{app_id}/identities', + body=json.dumps( + body, + default=pydantic_encoder, + ), + ) diff --git a/authomize/rest_api_client/client/async_platform_client.py b/authomize/rest_api_client/client/async_platform_client.py new file mode 100644 index 0000000..144607f --- /dev/null +++ b/authomize/rest_api_client/client/async_platform_client.py @@ -0,0 +1,38 @@ +from typing import Optional + +from authomize.rest_api_client.client.async_base_client import AsyncBaseClient +from authomize.rest_api_client.generated.external_rest_api.schemas import ( + IncidentExpansion, + IsAliveResponse, + MeResponse, + NonPaginatedResponseSchemaIncidentSchema, +) + + +class AsyncPlatformClient(AsyncBaseClient): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + + @property + def authorization_header(self) -> str: + return f'Bearer {self.auth_token}' + + async def is_alive(self) -> IsAliveResponse: + return await self.http_get('/is_alive') + + async def me(self) -> MeResponse: + return await self.http_get('/me') + + async def retrieve_incident( + self, + incident_id: str, + expand: Optional[list[IncidentExpansion]] = None, + ) -> NonPaginatedResponseSchemaIncidentSchema: + if not incident_id: + raise ValueError('Missing incident_id') + params = None + if expand: + params = dict( + expand=expand, + ) + return await self.http_get(f'/v2/incidents/{incident_id}', params=params) From fe16e561fd9d74b4ee58fed748dce6ee5a9089de Mon Sep 17 00:00:00 2001 From: Aashish Bhandari Date: Sun, 26 Feb 2023 15:26:36 +0545 Subject: [PATCH 2/4] Fixed async client (PR Changes) --- authomize/rest_api_client/client/__init__.py | 2 +- .../client/async_base_client.py | 99 ++-- .../rest_api_client/client/async_client.py | 47 +- .../rest_api_client/client/base_client.py | 68 --- authomize/rest_api_client/client/client.py | 348 -------------- .../client/connectors_client.py | 435 ------------------ .../rest_api_client/client/platform_client.py | 38 -- .../generated/connectors_rest_api/schemas.py | 104 ++--- setup.py | 1 + tests/test_import.py | 2 +- 10 files changed, 134 insertions(+), 1010 deletions(-) delete mode 100644 authomize/rest_api_client/client/base_client.py delete mode 100644 authomize/rest_api_client/client/client.py delete mode 100644 authomize/rest_api_client/client/connectors_client.py delete mode 100644 authomize/rest_api_client/client/platform_client.py diff --git a/authomize/rest_api_client/client/__init__.py b/authomize/rest_api_client/client/__init__.py index 82bd2d7..2790c8d 100644 --- a/authomize/rest_api_client/client/__init__.py +++ b/authomize/rest_api_client/client/__init__.py @@ -1,3 +1,3 @@ -from authomize.rest_api_client.client.client import Client +from authomize.rest_api_client.client.async_client import Client __all__ = ['Client'] diff --git a/authomize/rest_api_client/client/async_base_client.py b/authomize/rest_api_client/client/async_base_client.py index 806a3f9..3aa2d1f 100644 --- a/authomize/rest_api_client/client/async_base_client.py +++ b/authomize/rest_api_client/client/async_base_client.py @@ -1,7 +1,7 @@ from typing import Optional import aiohttp -from aiohttp import ClientResponse +from furl import furl # type: ignore AUTHOMIZE_API_URL = 'https://api.authomize.com' STATUS_OK: int = 200 @@ -15,7 +15,7 @@ def __init__(self, message): class AsyncBaseClient: def __init__(self, auth_token: str, base_url: str = AUTHOMIZE_API_URL): self.auth_token = auth_token - self.base_url = base_url + self.base_url = furl(base_url) self.session = aiohttp.ClientSession() self.session.headers.update({'Authorization': self.authorization_header}) @@ -24,47 +24,68 @@ def authorization_header(self) -> str: raise NotImplementedError() async def http_get(self, url, params=None): - url = self.base_url + url - response: ClientResponse = await self.session.get(url, params=params) - if response.status == STATUS_OK: - return response.json() - try: - response_json = await response.json() - detail = response_json.get('detail') - except Exception: - detail = None - if detail: - raise AsyncClientError(str(detail)) - response.raise_for_status() + url = self.base_url.join(url).url + async with self.session.get(url, params=params) as response: + if response.status == STATUS_OK: + return await response.json() + try: + response_json = await response.json() + detail = response_json.get('detail') + except Exception: + detail = None + if detail: + raise AsyncClientError(str(detail)) + response.raise_for_status() async def http_post(self, url: str, body: Optional[str] = None): - url = self.base_url + url - response = await self.session.post( + url = self.base_url.join(url).url + async with self.session.post( url, headers={'Content-Type': 'application/json'}, data=body, - ) - if response.status == STATUS_OK: - return await response.json() - try: - response_json = await response.json() - detail = response_json.get('detail') - except Exception: - detail = None - if detail: - raise AsyncClientError(str(detail)) - response.raise_for_status() + ) as response: + if response.status == STATUS_OK: + return await response.json() + try: + response_json = await response.json() + detail = response_json.get('detail') + except Exception: + detail = None + if detail: + raise AsyncClientError(str(detail)) + response.raise_for_status() + + async def http_patch(self, url: str, body: Optional[str] = None): + url = self.base_url.join(url).url + async with self.session.patch( + url, + headers={'Content-Type': 'application/json'}, + data=body, + ) as response: + if response.status == STATUS_OK: + return await response.json() + try: + response_json = await response.json() + detail = response_json.get('detail') + except Exception: + detail = None + if detail: + raise AsyncClientError(str(detail)) + response.raise_for_status() async def http_delete(self, url: str, params=None): - url = self.base_url + url - response = await self.session.delete(url, params=params) - if response.status == STATUS_OK: - return await response.json() - try: - response_json = await response.json() - detail = response_json.get('detail') - except Exception: - detail = None - if detail: - raise AsyncClientError(str(detail)) - response.raise_for_status() + url = self.base_url.join(url).url + async with self.session.delete(url, params=params) as response: + if response.status == STATUS_OK: + return await response.json() + try: + response_json = await response.json() + detail = response_json.get('detail') + except Exception: + detail = None + if detail: + raise AsyncClientError(str(detail)) + response.raise_for_status() + + async def close(self): + await self.session.close() diff --git a/authomize/rest_api_client/client/async_client.py b/authomize/rest_api_client/client/async_client.py index 79f83fd..142d803 100644 --- a/authomize/rest_api_client/client/async_client.py +++ b/authomize/rest_api_client/client/async_client.py @@ -1,11 +1,13 @@ +import asyncio +import functools from datetime import datetime from typing import Optional from apiclient_pydantic import serialize_all_methods, serialize_response +from authomize.rest_api_client.client.async_base_client import AUTHOMIZE_API_URL from authomize.rest_api_client.client.async_connectors_client import AsyncConnectorsClient from authomize.rest_api_client.client.async_platform_client import AsyncPlatformClient -from authomize.rest_api_client.client.base_client import AUTHOMIZE_API_URL from authomize.rest_api_client.generated.connectors_rest_api.schemas import ( BundleTransactionSchema, ItemsBundleSchema, @@ -49,8 +51,16 @@ ) +def syncify(func): + @functools.wraps(func) + def wrapped(*args, **kwargs): + return asyncio.ensure_future(func(*args, **kwargs)) + + return wrapped + + @serialize_all_methods(decorator=serialize_response) -class AsyncClient: +class Client: def __init__( self, *args, @@ -73,12 +83,15 @@ def __init__( **kwargs, ) + @syncify async def is_alive(self) -> IsAliveResponse: return await self.platform_client.is_alive() + @syncify async def me(self) -> MeResponse: return await self.platform_client.me() + @syncify async def list_connectors( self, params=None, @@ -87,6 +100,7 @@ async def list_connectors( params=params, ) + @syncify async def create_transaction( self, connector_id: str, @@ -95,6 +109,7 @@ async def create_transaction( connector_id=connector_id, ) + @syncify async def retrieve_transaction( self, connector_id: str, @@ -105,6 +120,7 @@ async def retrieve_transaction( transaction_id=transaction_id, ) + @syncify async def apply_transaction( self, connector_id: str, @@ -115,6 +131,7 @@ async def apply_transaction( transaction_id=transaction_id, ) + @syncify async def extend_transaction_items( self, connector_id: str, @@ -127,6 +144,7 @@ async def extend_transaction_items( items=items, ) + @syncify async def delete_app_data( self, app_id: str, @@ -137,6 +155,7 @@ async def delete_app_data( modified_before=modified_before, ) + @syncify async def search_users( self, app_id: str, @@ -147,6 +166,7 @@ async def search_users( start_date=start_date, ) + @syncify async def create_users( self, app_id: str, @@ -157,6 +177,7 @@ async def create_users( body=body, ) + @syncify async def search_groupings( self, app_id: str, @@ -167,6 +188,7 @@ async def search_groupings( start_date=start_date, ) + @syncify async def create_groupings( self, app_id: str, @@ -177,6 +199,7 @@ async def create_groupings( body=body, ) + @syncify async def search_permissions( self, app_id: str, @@ -187,6 +210,7 @@ async def search_permissions( start_date=start_date, ) + @syncify async def create_permissions( self, app_id: str, @@ -197,6 +221,7 @@ async def create_permissions( body=body, ) + @syncify async def search_privileges( self, app_id: str, @@ -207,6 +232,7 @@ async def search_privileges( start_date=start_date, ) + @syncify async def create_privileges( self, app_id: str, @@ -217,6 +243,7 @@ async def create_privileges( body=body, ) + @syncify async def search_privileges_grants( self, app_id: str, @@ -227,6 +254,7 @@ async def search_privileges_grants( start_date=start_date, ) + @syncify async def create_privileges_grants( self, app_id: str, @@ -237,6 +265,7 @@ async def create_privileges_grants( body=body, ) + @syncify async def search_accounts_association( self, app_id: str, @@ -247,6 +276,7 @@ async def search_accounts_association( start_date=start_date, ) + @syncify async def create_accounts_association( self, app_id: str, @@ -257,6 +287,7 @@ async def create_accounts_association( body=body, ) + @syncify async def search_groupings_association( self, app_id: str, @@ -267,6 +298,7 @@ async def search_groupings_association( start_date=start_date, ) + @syncify async def create_groupings_association( self, app_id: str, @@ -277,6 +309,7 @@ async def create_groupings_association( body=body, ) + @syncify async def search_assets( self, app_id: str, @@ -287,6 +320,7 @@ async def search_assets( start_date=start_date, ) + @syncify async def create_assets( self, app_id: str, @@ -297,6 +331,7 @@ async def create_assets( body=body, ) + @syncify async def search_assets_inheritance( self, app_id: str, @@ -307,6 +342,7 @@ async def search_assets_inheritance( start_date=start_date, ) + @syncify async def create_assets_inheritance( self, app_id: str, @@ -317,6 +353,7 @@ async def create_assets_inheritance( body=body, ) + @syncify async def search_identities( self, app_id: str, @@ -327,6 +364,7 @@ async def search_identities( start_date=start_date, ) + @syncify async def create_identities( self, app_id: str, @@ -337,6 +375,7 @@ async def create_identities( body=body, ) + @syncify async def retrieve_incident( self, incident_id: str, @@ -346,3 +385,7 @@ async def retrieve_incident( incident_id=incident_id, expand=expand, ) + + @syncify + async def close(self): + await asyncio.gather(self.connectors_client.close(), self.platform_client.close()) diff --git a/authomize/rest_api_client/client/base_client.py b/authomize/rest_api_client/client/base_client.py deleted file mode 100644 index 1f9f85f..0000000 --- a/authomize/rest_api_client/client/base_client.py +++ /dev/null @@ -1,68 +0,0 @@ -from typing import Optional - -import requests - -AUTHOMIZE_API_URL = 'https://api.authomize.com' - - -class ClientError(Exception): - def __init__(self, message): - self.message = message - - -class BaseClient: - def __init__(self, auth_token: str, base_url: str = AUTHOMIZE_API_URL): - self.auth_token = auth_token - self.base_url = base_url - self.session = requests.Session() - self.session.headers.update({'Authorization': self.authorization_header}) - - @property - def authorization_header(self) -> str: - raise NotImplementedError() - - def http_get(self, url, params=None): - url = self.base_url + url - response = self.session.get(url, params=params) - if response.ok: - return response.json() - try: - response_json = response.json() - detail = response_json.get('detail') - except Exception: - detail = None - if detail: - raise ClientError(str(detail)) - response.raise_for_status() - - def http_post(self, url: str, body: Optional[str] = None): - url = self.base_url + url - response = self.session.post( - url, - headers={'Content-Type': 'application/json'}, - data=body, - ) - if response.ok: - return response.json() - try: - response_json = response.json() - detail = response_json.get('detail') - except Exception: - detail = None - if detail: - raise ClientError(str(detail)) - response.raise_for_status() - - def http_delete(self, url: str, params=None): - url = self.base_url + url - response = self.session.delete(url, params=params) - if response.ok: - return response.json() - try: - response_json = response.json() - detail = response_json.get('detail') - except Exception: - detail = None - if detail: - raise ClientError(str(detail)) - response.raise_for_status() diff --git a/authomize/rest_api_client/client/client.py b/authomize/rest_api_client/client/client.py deleted file mode 100644 index 9cd4d88..0000000 --- a/authomize/rest_api_client/client/client.py +++ /dev/null @@ -1,348 +0,0 @@ -from datetime import datetime -from typing import Optional - -from apiclient_pydantic import serialize_all_methods, serialize_response - -from authomize.rest_api_client.client.base_client import AUTHOMIZE_API_URL -from authomize.rest_api_client.client.connectors_client import ConnectorsClient -from authomize.rest_api_client.client.platform_client import PlatformClient -from authomize.rest_api_client.generated.connectors_rest_api.schemas import ( - BundleTransactionSchema, - ItemsBundleSchema, - NewAccountsAssociationResponseSchema, - NewAccountsAssociationsListRequestSchema, - NewAssetsInheritanceListRequestSchema, - NewAssetsInheritanceResponseSchema, - NewAssetsListRequestSchema, - NewAssetsResponseSchema, - NewGroupingResponseSchema, - NewGroupingsAssociationResponseSchema, - NewGroupingsAssociationsListRequestSchema, - NewGroupingsListRequestSchema, - NewIdentitiesListRequestSchema, - NewIdentityResponseSchema, - NewPermissionsListRequestSchema, - NewPermissionsResponseSchema, - NewPrivilegeGrantsResponseSchema, - NewPrivilegesGrantsListRequestSchema, - NewPrivilegesListRequestSchema, - NewPrivilegesResponseSchema, - NewUserResponseSchema, - NewUsersListRequestSchema, - RestApiConnectorListSchema, - SearchAccountsAssociationsListResponseSchema, - SearchAssetsInheritanceListResponseSchema, - SearchAssetsListResponseSchema, - SearchGroupingResponseSchema, - SearchGroupingsAssociationsListResponseSchema, - SearchIdentitiesListResponseSchema, - SearchPermissionResponseSchema, - SearchPrivilegeGrantsListResponseSchema, - SearchPrivilegesListResponseSchema, - SearchUsersListResponseSchema, - SubmitResponse, -) -from authomize.rest_api_client.generated.external_rest_api.schemas import ( - IncidentExpansion, - IsAliveResponse, - MeResponse, -) - - -@serialize_all_methods(decorator=serialize_response) -class Client: - def __init__( - self, - *args, - auth_token: str, - base_url: str = AUTHOMIZE_API_URL, - **kwargs, - ): - self.auth_token = auth_token - self.base_url = base_url - self.connectors_client = ConnectorsClient( - *args, - auth_token=auth_token, - base_url=base_url, - **kwargs, - ) - self.platform_client = PlatformClient( - *args, - auth_token=auth_token, - base_url=base_url, - **kwargs, - ) - - def is_alive(self) -> IsAliveResponse: - return self.platform_client.is_alive() - - def me(self) -> MeResponse: - return self.platform_client.me() - - def list_connectors( - self, - params=None, - ) -> RestApiConnectorListSchema: - return self.connectors_client.list_connectors( - params=params, - ) - - def create_transaction( - self, - connector_id: str, - ) -> BundleTransactionSchema: - return self.connectors_client.create_transaction( - connector_id=connector_id, - ) - - def retrieve_transaction( - self, - connector_id: str, - transaction_id: str, - ) -> BundleTransactionSchema: - return self.connectors_client.retrieve_transaction( - connector_id=connector_id, - transaction_id=transaction_id, - ) - - def apply_transaction( - self, - connector_id: str, - transaction_id: str, - ) -> BundleTransactionSchema: - return self.connectors_client.apply_transaction( - connector_id=connector_id, - transaction_id=transaction_id, - ) - - def extend_transaction_items( - self, - connector_id: str, - transaction_id: str, - items: ItemsBundleSchema, - ) -> SubmitResponse: - return self.connectors_client.extend_transaction_items( - connector_id=connector_id, - transaction_id=transaction_id, - items=items, - ) - - def delete_app_data( - self, - app_id: str, - modified_before: Optional[datetime] = None, - ) -> SubmitResponse: - return self.connectors_client.delete_app_data( - app_id=app_id, - modified_before=modified_before, - ) - - def search_users( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchUsersListResponseSchema: - return self.connectors_client.search_users( - app_id=app_id, - start_date=start_date, - ) - - def create_users( - self, - app_id: str, - body: NewUsersListRequestSchema, - ) -> NewUserResponseSchema: - return self.connectors_client.create_users( - app_id=app_id, - body=body, - ) - - def search_groupings( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchGroupingResponseSchema: - return self.connectors_client.search_groupings( - app_id=app_id, - start_date=start_date, - ) - - def create_groupings( - self, - app_id: str, - body: NewGroupingsListRequestSchema, - ) -> NewGroupingResponseSchema: - return self.connectors_client.create_groupings( - app_id=app_id, - body=body, - ) - - def search_permissions( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchPermissionResponseSchema: - return self.connectors_client.search_permissions( - app_id=app_id, - start_date=start_date, - ) - - def create_permissions( - self, - app_id: str, - body: NewPermissionsListRequestSchema, - ) -> NewPermissionsResponseSchema: - return self.connectors_client.create_permissions( - app_id=app_id, - body=body, - ) - - def search_privileges( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchPrivilegesListResponseSchema: - return self.connectors_client.search_privileges( - app_id=app_id, - start_date=start_date, - ) - - def create_privileges( - self, - app_id: str, - body: NewPrivilegesListRequestSchema, - ) -> NewPrivilegesResponseSchema: - return self.connectors_client.create_privileges( - app_id=app_id, - body=body, - ) - - def search_privileges_grants( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchPrivilegeGrantsListResponseSchema: - return self.connectors_client.search_privileges_grants( - app_id=app_id, - start_date=start_date, - ) - - def create_privileges_grants( - self, - app_id: str, - body: NewPrivilegesGrantsListRequestSchema, - ) -> NewPrivilegeGrantsResponseSchema: - return self.connectors_client.create_privileges_grants( - app_id=app_id, - body=body, - ) - - def search_accounts_association( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchAccountsAssociationsListResponseSchema: - return self.connectors_client.search_accounts_association( - app_id=app_id, - start_date=start_date, - ) - - def create_accounts_association( - self, - app_id: str, - body: NewAccountsAssociationsListRequestSchema, - ) -> NewAccountsAssociationResponseSchema: - return self.connectors_client.create_accounts_association( - app_id=app_id, - body=body, - ) - - def search_groupings_association( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchGroupingsAssociationsListResponseSchema: - return self.connectors_client.search_groupings_association( - app_id=app_id, - start_date=start_date, - ) - - def create_groupings_association( - self, - app_id: str, - body: NewGroupingsAssociationsListRequestSchema, - ) -> NewGroupingsAssociationResponseSchema: - return self.connectors_client.create_groupings_association( - app_id=app_id, - body=body, - ) - - def search_assets( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchAssetsListResponseSchema: - return self.connectors_client.search_assets( - app_id=app_id, - start_date=start_date, - ) - - def create_assets( - self, - app_id: str, - body: NewAssetsListRequestSchema, - ) -> NewAssetsResponseSchema: - return self.connectors_client.create_assets( - app_id=app_id, - body=body, - ) - - def search_assets_inheritance( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchAssetsInheritanceListResponseSchema: - return self.connectors_client.search_assets_inheritance( - app_id=app_id, - start_date=start_date, - ) - - def create_assets_inheritance( - self, - app_id: str, - body: NewAssetsInheritanceListRequestSchema, - ) -> NewAssetsInheritanceResponseSchema: - return self.connectors_client.create_assets_inheritance( - app_id=app_id, - body=body, - ) - - def search_identities( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchIdentitiesListResponseSchema: - return self.connectors_client.search_identities( - app_id=app_id, - start_date=start_date, - ) - - def create_identities( - self, - app_id: str, - body: NewIdentitiesListRequestSchema, - ) -> NewIdentityResponseSchema: - return self.connectors_client.create_identities( - app_id=app_id, - body=body, - ) - - def retrieve_incident( - self, - incident_id: str, - expand: Optional[list[IncidentExpansion]] = None, - ): - return self.platform_client.retrieve_incident( - incident_id=incident_id, - expand=expand, - ) diff --git a/authomize/rest_api_client/client/connectors_client.py b/authomize/rest_api_client/client/connectors_client.py deleted file mode 100644 index c810134..0000000 --- a/authomize/rest_api_client/client/connectors_client.py +++ /dev/null @@ -1,435 +0,0 @@ -import json -from datetime import datetime -from typing import Optional - -from pydantic.json import pydantic_encoder - -from authomize.rest_api_client.client.base_client import BaseClient -from authomize.rest_api_client.generated.connectors_rest_api.schemas import ( - BundleTransactionSchema, - ItemsBundleSchema, - NewAccountsAssociationResponseSchema, - NewAccountsAssociationsListRequestSchema, - NewAssetsInheritanceListRequestSchema, - NewAssetsInheritanceResponseSchema, - NewAssetsListRequestSchema, - NewAssetsResponseSchema, - NewGroupingResponseSchema, - NewGroupingsAssociationResponseSchema, - NewGroupingsAssociationsListRequestSchema, - NewGroupingsListRequestSchema, - NewIdentitiesListRequestSchema, - NewIdentityResponseSchema, - NewPermissionsListRequestSchema, - NewPermissionsResponseSchema, - NewPrivilegeGrantsResponseSchema, - NewPrivilegesGrantsListRequestSchema, - NewPrivilegesListRequestSchema, - NewPrivilegesResponseSchema, - NewUserResponseSchema, - NewUsersListRequestSchema, - RestApiConnectorListSchema, - SearchAccountsAssociationsListResponseSchema, - SearchAssetsInheritanceListResponseSchema, - SearchAssetsListResponseSchema, - SearchGroupingResponseSchema, - SearchGroupingsAssociationsListResponseSchema, - SearchIdentitiesListResponseSchema, - SearchPermissionResponseSchema, - SearchPrivilegeGrantsListResponseSchema, - SearchPrivilegesListResponseSchema, - SearchUsersListResponseSchema, - SubmitResponse, -) - - -class ConnectorsClient(BaseClient): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - @property - def authorization_header(self) -> str: - return self.auth_token - - def list_connectors( - self, - params=None, - ) -> RestApiConnectorListSchema: - return self.http_get('/v1/connectors', params=params) - - def create_transaction( - self, - connector_id: str, - ) -> BundleTransactionSchema: - if not connector_id: - raise ValueError('Missing connector_id') - return self.http_post(f'/v1/connectors/{connector_id}/transactions') - - def retrieve_transaction( - self, - connector_id: str, - transaction_id: str, - ) -> BundleTransactionSchema: - if not connector_id: - raise ValueError('Missing connector_id') - if not transaction_id: - raise ValueError('Missing transaction_id') - return self.http_get(f'/v1/connectors/{connector_id}/transactions/{transaction_id}') - - def apply_transaction( - self, - connector_id: str, - transaction_id: str, - ) -> BundleTransactionSchema: - if not connector_id: - raise ValueError('Missing connector_id') - if not transaction_id: - raise ValueError('Missing transaction_id') - return self.http_post(f'/v1/connectors/{connector_id}/transactions/{transaction_id}/apply') - - def extend_transaction_items( - self, - connector_id: str, - transaction_id: str, - items: ItemsBundleSchema, - ) -> SubmitResponse: - if not connector_id: - raise ValueError('Missing connector_id') - if not transaction_id: - raise ValueError('Missing transaction_id') - return self.http_post( - f'/v1/connectors/{connector_id}/transactions/{transaction_id}/items', - body=items.json(), - ) - - def delete_app_data( - self, - app_id: str, - modified_before: Optional[datetime] = None, - ) -> SubmitResponse: - if not app_id: - raise ValueError('Missing app_id') - date_filter = '' - if modified_before: - date_filter = f'?modifiedBefore={str(modified_before)}' - return self.http_delete(url=f"/v2/apps/{app_id}/data{date_filter}") - - def search_users( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchUsersListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/accounts/users', - params={ - **params, - }, - ) - - def create_users( - self, - app_id: str, - body: NewUsersListRequestSchema, - ) -> NewUserResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/accounts/users', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_groupings( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchGroupingResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/access/grouping', - params={ - **params, - }, - ) - - def create_groupings( - self, - app_id: str, - body: NewGroupingsListRequestSchema, - ) -> NewGroupingResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/access/grouping', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_permissions( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchPermissionResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/access/permissions', - params={ - **params, - }, - ) - - def create_permissions( - self, - app_id: str, - body: NewPermissionsListRequestSchema, - ) -> NewPermissionsResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/access/permissions', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_privileges( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchPrivilegesListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/privileges', - params={ - **params, - }, - ) - - def create_privileges( - self, - app_id: str, - body: NewPrivilegesListRequestSchema, - ) -> NewPrivilegesResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/privileges', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_privileges_grants( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchPrivilegeGrantsListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/privileges/grants', - params={ - **params, - }, - ) - - def create_privileges_grants( - self, - app_id: str, - body: NewPrivilegesGrantsListRequestSchema, - ) -> NewPrivilegeGrantsResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/privileges/grants', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_accounts_association( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchAccountsAssociationsListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/association/accounts', - params={ - **params, - }, - ) - - def create_accounts_association( - self, - app_id: str, - body: NewAccountsAssociationsListRequestSchema, - ) -> NewAccountsAssociationResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/association/accounts', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_groupings_association( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchGroupingsAssociationsListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/association/groupings', - params={ - **params, - }, - ) - - def create_groupings_association( - self, - app_id: str, - body: NewGroupingsAssociationsListRequestSchema, - ) -> NewGroupingsAssociationResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/association/groupings', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_assets( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchAssetsListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/assets', - params={ - **params, - }, - ) - - def create_assets( - self, - app_id: str, - body: NewAssetsListRequestSchema, - ) -> NewAssetsResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/assets', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_assets_inheritance( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchAssetsInheritanceListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/assets/inheritance', - params={ - **params, - }, - ) - - def create_assets_inheritance( - self, - app_id: str, - body: NewAssetsInheritanceListRequestSchema, - ) -> NewAssetsInheritanceResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/assets/inheritance', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) - - def search_identities( - self, - app_id: str, - start_date: Optional[datetime] = None, - ) -> SearchIdentitiesListResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - params = dict( - start_date=start_date, - ) - return self.http_get( - url=f'/v2/apps/{app_id}/identities', - params={ - **params, - }, - ) - - def create_identities( - self, - app_id: str, - body: NewIdentitiesListRequestSchema, - ) -> NewIdentityResponseSchema: - if not app_id: - raise ValueError('Missing app_id') - return self.http_post( - url=f'/v2/apps/{app_id}/identities', - body=json.dumps( - body, - default=pydantic_encoder, - ), - ) diff --git a/authomize/rest_api_client/client/platform_client.py b/authomize/rest_api_client/client/platform_client.py deleted file mode 100644 index 5148e4d..0000000 --- a/authomize/rest_api_client/client/platform_client.py +++ /dev/null @@ -1,38 +0,0 @@ -from typing import Optional - -from authomize.rest_api_client.client.base_client import BaseClient -from authomize.rest_api_client.generated.external_rest_api.schemas import ( - IncidentExpansion, - IsAliveResponse, - MeResponse, - NonPaginatedResponseSchemaIncidentSchema, -) - - -class PlatformClient(BaseClient): - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - - @property - def authorization_header(self) -> str: - return f'Bearer {self.auth_token}' - - def is_alive(self) -> IsAliveResponse: - return self.http_get('/is_alive') - - def me(self) -> MeResponse: - return self.http_get('/me') - - def retrieve_incident( - self, - incident_id: str, - expand: Optional[list[IncidentExpansion]] = None, - ) -> NonPaginatedResponseSchemaIncidentSchema: - if not incident_id: - raise ValueError('Missing incident_id') - params = None - if expand: - params = dict( - expand=expand, - ) - return self.http_get(f'/v2/incidents/{incident_id}', params=params) diff --git a/authomize/rest_api_client/generated/connectors_rest_api/schemas.py b/authomize/rest_api_client/generated/connectors_rest_api/schemas.py index f8f9896..eef0adf 100644 --- a/authomize/rest_api_client/generated/connectors_rest_api/schemas.py +++ b/authomize/rest_api_client/generated/connectors_rest_api/schemas.py @@ -792,9 +792,7 @@ class SearchAccountsAssociationsListResponseSchema(BaseModel): class SearchAssetsInheritanceListResponseSchema(BaseModel): - data: List[AssetInheritanceSchema] = Field( - ..., description='Assets Inheritance', title='Data' - ) + data: List[AssetInheritanceSchema] = Field(..., description='Assets Inheritance', title='Data') class SearchGroupingsAssociationsListResponseSchema(BaseModel): @@ -804,9 +802,7 @@ class SearchGroupingsAssociationsListResponseSchema(BaseModel): class SearchPrivilegeGrantsListResponseSchema(BaseModel): - data: List[PrivilegeGrantSchema] = Field( - ..., description='Privilege Grants', title='Data' - ) + data: List[PrivilegeGrantSchema] = Field(..., description='Privilege Grants', title='Data') class ServiceDescription(BaseModel): @@ -1132,18 +1128,12 @@ class IdentitySchema(BaseModel): title='Originid', ) name: Optional[str] = Field(None, description='Username', title='Name') - email: Optional[str] = Field( - None, description="User's work email address.\n", title='Email' - ) + email: Optional[str] = Field(None, description="User's work email address.\n", title='Email') personalEmail: Optional[str] = Field( None, description="User's personal email address.\n", title='Personalemail' ) - firstName: Optional[str] = Field( - None, description="User's first name\n", title='Firstname' - ) - lastName: Optional[str] = Field( - None, description="The user's last name.\n", title='Lastname' - ) + firstName: Optional[str] = Field(None, description="User's first name\n", title='Firstname') + lastName: Optional[str] = Field(None, description="The user's last name.\n", title='Lastname') employeeNumber: Optional[str] = Field( None, description='Employee number', title='Employeenumber' ) @@ -1163,9 +1153,7 @@ class IdentitySchema(BaseModel): description="The identity's division in their organization.\n", title='Division', ) - title: Optional[str] = Field( - None, description="The user's job title.\n", title='Title' - ) + title: Optional[str] = Field(None, description="The user's job title.\n", title='Title') managerId: Optional[str] = Field( None, description="The manager identity's ID.\n", title='Managerid' ) @@ -1196,9 +1184,7 @@ class ItemsBundleSchema(BaseModel): inheritanceIdentities: Optional[List[IdentitiesInheritance]] = Field( None, title='Inheritanceidentities' ) - inheritanceAssets: Optional[List[AssetsInheritance]] = Field( - None, title='Inheritanceassets' - ) + inheritanceAssets: Optional[List[AssetsInheritance]] = Field(None, title='Inheritanceassets') access: Optional[List[AccessDescription]] = Field(None, title='Access') @@ -1212,18 +1198,12 @@ class NewIdentityRequestSchema(BaseModel): title='Originid', ) name: Optional[str] = Field(None, description='Username', title='Name') - email: Optional[str] = Field( - None, description="User's work email address.\n", title='Email' - ) + email: Optional[str] = Field(None, description="User's work email address.\n", title='Email') personalEmail: Optional[str] = Field( None, description="User's personal email address.\n", title='Personalemail' ) - firstName: Optional[str] = Field( - None, description="User's first name\n", title='Firstname' - ) - lastName: Optional[str] = Field( - None, description="The user's last name.\n", title='Lastname' - ) + firstName: Optional[str] = Field(None, description="User's first name\n", title='Firstname') + lastName: Optional[str] = Field(None, description="The user's last name.\n", title='Lastname') employeeNumber: Optional[str] = Field( None, description='Employee number', title='Employeenumber' ) @@ -1243,9 +1223,7 @@ class NewIdentityRequestSchema(BaseModel): description="The identity's division in their organization.\n", title='Division', ) - title: Optional[str] = Field( - None, description="The user's job title.\n", title='Title' - ) + title: Optional[str] = Field(None, description="The user's job title.\n", title='Title') managerId: Optional[str] = Field( None, description="The manager identity's ID.\n", title='Managerid' ) @@ -1350,15 +1328,9 @@ class NewUserRequestSchema(BaseModel): title='Originid', ) name: Optional[str] = Field(None, description='Username\n', title='Name') - email: Optional[str] = Field( - None, description="User's email address.", title='Email' - ) - firstName: Optional[str] = Field( - None, description="User's first name\n", title='Firstname' - ) - lastName: Optional[str] = Field( - None, description="The user's last name.\n", title='Lastname' - ) + email: Optional[str] = Field(None, description="User's email address.", title='Email') + firstName: Optional[str] = Field(None, description="User's first name\n", title='Firstname') + lastName: Optional[str] = Field(None, description="The user's last name.\n", title='Lastname') status: Optional[UserStatus] = Field( None, description='User status must be: `Deleted`, `Disabled`, `Enabled`, `Staged`, `Suspended`, or `Unknown`.\n', @@ -1468,16 +1440,12 @@ class RequestsBundleSchema(BaseModel): description='This API enables you to establish inheritance between privileges, so that a single privilege contains a set of other privileges. For example, an Administrative privilege that contains read and write privileges.', title='New Privileges Grants', ) - new_accounts_association: Optional[ - List[NewAccountsAssociationRequestSchema] - ] = Field( + new_accounts_association: Optional[List[NewAccountsAssociationRequestSchema]] = Field( None, description='Create association between user accounts and groups.', title='New Accounts Association', ) - new_groupings_association: Optional[ - List[NewGroupingsAssociationRequestSchema] - ] = Field( + new_groupings_association: Optional[List[NewGroupingsAssociationRequestSchema]] = Field( None, description='Create associations between groups and other groups.\n', title='New Groupings Association', @@ -1551,18 +1519,12 @@ class UpdateIdentityRequestSchema(BaseModel): title='Originid', ) name: Optional[str] = Field(None, description='Username', title='Name') - email: Optional[str] = Field( - None, description="User's work email address.\n", title='Email' - ) + email: Optional[str] = Field(None, description="User's work email address.\n", title='Email') personalEmail: Optional[str] = Field( None, description="User's personal email address.\n", title='Personalemail' ) - firstName: Optional[str] = Field( - None, description="User's first name\n", title='Firstname' - ) - lastName: Optional[str] = Field( - None, description="The user's last name.\n", title='Lastname' - ) + firstName: Optional[str] = Field(None, description="User's first name\n", title='Firstname') + lastName: Optional[str] = Field(None, description="The user's last name.\n", title='Lastname') employeeNumber: Optional[str] = Field( None, description='Employee number', title='Employeenumber' ) @@ -1582,9 +1544,7 @@ class UpdateIdentityRequestSchema(BaseModel): description="The identity's division in their organization.\n", title='Division', ) - title: Optional[str] = Field( - None, description="The user's job title.\n", title='Title' - ) + title: Optional[str] = Field(None, description="The user's job title.\n", title='Title') managerId: Optional[str] = Field( None, description="The manager identity's ID.\n", title='Managerid' ) @@ -1620,15 +1580,9 @@ class UpdateUserRequestSchema(BaseModel): title='Originid', ) name: Optional[str] = Field(None, description='Username\n', title='Name') - email: Optional[str] = Field( - None, description="User's email address.", title='Email' - ) - firstName: Optional[str] = Field( - None, description="User's first name\n", title='Firstname' - ) - lastName: Optional[str] = Field( - None, description="The user's last name.\n", title='Lastname' - ) + email: Optional[str] = Field(None, description="User's email address.", title='Email') + firstName: Optional[str] = Field(None, description="User's first name\n", title='Firstname') + lastName: Optional[str] = Field(None, description="The user's last name.\n", title='Lastname') status: Optional[UserStatus] = Field( None, description='User status must be: `Deleted`, `Disabled`, `Enabled`, `Staged`, `Suspended`, or `Unknown`.\n', @@ -1668,15 +1622,9 @@ class UserSchema(BaseModel): title='Originid', ) name: Optional[str] = Field(None, description='Username\n', title='Name') - email: Optional[str] = Field( - None, description="User's email address.", title='Email' - ) - firstName: Optional[str] = Field( - None, description="User's first name\n", title='Firstname' - ) - lastName: Optional[str] = Field( - None, description="The user's last name.\n", title='Lastname' - ) + email: Optional[str] = Field(None, description="User's email address.", title='Email') + firstName: Optional[str] = Field(None, description="User's first name\n", title='Firstname') + lastName: Optional[str] = Field(None, description="The user's last name.\n", title='Lastname') status: Optional[UserStatus] = Field( None, description='User status must be: `Deleted`, `Disabled`, `Enabled`, `Staged`, `Suspended`, or `Unknown`.\n', diff --git a/setup.py b/setup.py index be2a60d..89b5193 100644 --- a/setup.py +++ b/setup.py @@ -29,6 +29,7 @@ 'pyhamcrest~=2.0', 'pytest~=6.2', 'pytest-html~=2.1', + 'furl~=2.1.3', 'types-requests~=2.28.7', ], 'codegen': [ diff --git a/tests/test_import.py b/tests/test_import.py index c1aa00e..600231b 100644 --- a/tests/test_import.py +++ b/tests/test_import.py @@ -1,5 +1,5 @@ """Make sure we have single test""" -from authomize.rest_api_client import Client +from authomize.rest_api_client.client.async_client import Client def test_import(): From 362e233ea9187e2d9aea3b3d1303b219660ab3db Mon Sep 17 00:00:00 2001 From: Aashish Bhandari Date: Sun, 26 Feb 2023 15:29:52 +0545 Subject: [PATCH 3/4] Adding reqs --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 89b5193..ec1a7ba 100644 --- a/setup.py +++ b/setup.py @@ -31,6 +31,7 @@ 'pytest-html~=2.1', 'furl~=2.1.3', 'types-requests~=2.28.7', + 'aiohttp~=3.8.4', ], 'codegen': [ 'datamodel-code-generator~=0.11', From a0dfc81fd335f1818b1bf41d63297cfa9f2e4264 Mon Sep 17 00:00:00 2001 From: Aashish Bhandari Date: Thu, 9 Mar 2023 14:29:21 +0545 Subject: [PATCH 4/4] Fixed header parse failure for missing AUTH Token --- authomize/rest_api_client/client/async_base_client.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/authomize/rest_api_client/client/async_base_client.py b/authomize/rest_api_client/client/async_base_client.py index 3aa2d1f..c3da90d 100644 --- a/authomize/rest_api_client/client/async_base_client.py +++ b/authomize/rest_api_client/client/async_base_client.py @@ -17,7 +17,7 @@ def __init__(self, auth_token: str, base_url: str = AUTHOMIZE_API_URL): self.auth_token = auth_token self.base_url = furl(base_url) self.session = aiohttp.ClientSession() - self.session.headers.update({'Authorization': self.authorization_header}) + self.session.headers.update({'Authorization': self.authorization_header or ""}) @property def authorization_header(self) -> str: