Skip to content

Commit

Permalink
Nylas Credentials API v3 (#293)
Browse files Browse the repository at this point in the history
New PR for Credentials API support. Introduced a new class for UpdateRequest and fixed other issues with typing
  • Loading branch information
kraju3 authored Oct 18, 2023
1 parent 530ab77 commit c22e301
Show file tree
Hide file tree
Showing 4 changed files with 198 additions and 0 deletions.
85 changes: 85 additions & 0 deletions nylas/models/credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from dataclasses import dataclass
from typing import Dict, Optional, Literal, Union

from dataclasses_json import dataclass_json
from typing_extensions import TypedDict, Protocol, NotRequired

CredentialType = Literal["adminconsent", "serviceaccount", "connector"]


@dataclass_json
@dataclass
class Credential:
"""
Interface representing a Nylas Credential object.
Attributes
id: Globally unique object identifier;
name: Name of the credential
credential_type: The type of credential
hashed_data: Hashed value of the credential that you created
created_at: Timestamp of when the credential was created
updated_at: Timestamp of when the credential was updated;
"""
id: str
name: str
credential_type: Optional[CredentialType] = None
hashed_data: Optional[str] = None
created_at: Optional[int] = None
updated_at: Optional[int] = None


class MicrosoftAdminConsentSettings(Protocol):
client_id: str
client_secret: str


class GoogleServiceAccountCredential(Protocol):
private_key_id: str
private_key: str
client_email: str


CredentialData = Union[MicrosoftAdminConsentSettings, GoogleServiceAccountCredential, Dict[str, any]]


class CredentialRequest(TypedDict):
"""
Interface representing a request to create a credential.
Attributes:
name: Name of the credential
credential_type: Type of credential you want to create.
credential_data: The data required to successfully create the credential object
"""
name: Optional[str]
credential_type: CredentialType
credential_data: CredentialData

class UpdateCredentialRequest(TypedDict):
"""
Interface representing a request to update a credential.
Attributes:
name: Name of the credential
credential_data: The data required to successfully create the credential object
"""
name: Optional[str]
credential_data: Optional[CredentialData]

class ListCredentialQueryParams(TypedDict):
"""
Interface representing the query parameters for credentials .
Attributes:
offset: Offset results
sort_by: Sort entries by field name
order_by: Order results by the specified field.
Currently only start is supported.
limit: The maximum number of objects to return.
This field defaults to 50. The maximum allowed value is 200.
"""

limit: NotRequired[int]
offset: NotRequired[int]
order_by: NotRequired[str]
sort_by: NotRequired[str]
1 change: 1 addition & 0 deletions nylas/resources/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def _build_query_with_admin_consent(config: dict) -> dict:


class Auth(Resource):

@property
def grants(self) -> Grants:
"""
Expand Down
11 changes: 11 additions & 0 deletions nylas/resources/connectors.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from nylas.resources.credentials import Credentials

from nylas.handler.api_resources import (
ListableApiResource,
FindableApiResource,
Expand All @@ -22,6 +24,15 @@ class Connectors(
UpdatableApiResource,
DestroyableApiResource,
):
@property
def credentials(self) -> Credentials:
"""
Access the Credentials API.
Returns:
The Credentials API.
"""
return Credentials(self._http_client)
def list(self, query_params: ListConnectorQueryParams) -> ListResponse[Connector]:
"""
Return all Connectors.
Expand Down
101 changes: 101 additions & 0 deletions nylas/resources/credentials.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from nylas.handler.api_resources import (
ListableApiResource,
FindableApiResource,
CreatableApiResource,
UpdatableApiResource,
DestroyableApiResource,
)
from nylas.models.auth import Provider
from nylas.models.credentials import (
Credential,
CredentialRequest, ListCredentialQueryParams, UpdateCredentialRequest
)
from nylas.models.response import Response, ListResponse, DeleteResponse


class Credentials(
ListableApiResource,
FindableApiResource,
CreatableApiResource,
UpdatableApiResource,
DestroyableApiResource,
):
def list(self, provider: Provider, query_params: ListCredentialQueryParams = None) -> ListResponse[Credential]:
"""
Return all credentials for a particular provider.
Args:
provider: The provider.
query_params: The query parameters to include in the request.
Returns:
The list of credentials.
"""

return super(Credentials, self).list(path=f"/v3/connectors/{provider}/creds", response_type=Credential,
query_params=query_params)

def find(self, provider: Provider, credential_id: str) -> Response[Credential]:
"""
Return a credential.
Args:
provider: The provider of the credential.
credential_id: The ID of the credential to retrieve.
Returns:
The Credential.
"""

return super(Credentials, self).find(
path=f"/v3/connectors/{provider}/creds/{credential_id}", response_type=Credential
)

def create(self, provider: Provider, request_body: CredentialRequest) -> Response[Credential]:
"""
Create a credential for a particular provider.
Args:
provider: The provider.
request_body: The values to create the Credential with.
Returns:
The created Credential.
"""

return super(Credentials, self).create(
path=f"/v3/connectors/{provider}/creds", response_type=Credential, request_body=request_body
)

def update(self, provider: Provider, credential_id: str, request_body: UpdateCredentialRequest) -> Response[Credential]:
"""
Update a credential.
Args:
provider: The provider.
credential_id: The ID of the credential to update.
request_body: The values to update the credential with.
Returns:
The updated credential.
"""

return super(Credentials, self).update(
path=f"/v3/connectors/{provider}/creds/{credential_id}", response_type=Credential,
request_body=request_body,
method="PATCH"
)

def destroy(self, provider: Provider, credential_id: str) -> DeleteResponse:
"""
Delete a credential.
Args:
provider: the provider for the grant
credential_id: The ID of the credential to delete.
Returns:
The deletion response.
"""

return super(Credentials, self).destroy(path=f"/v3/connectors/{provider}/creds/{credential_id}")

0 comments on commit c22e301

Please sign in to comment.