-
Notifications
You must be signed in to change notification settings - Fork 76
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for Read, Update, and Delete for Messages #305
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
7ea3633
Add support for Read, Update, and Delete for Messages
spang 05e78fa
NotRequired doesn't seem to work to specify optional items on datacla…
spang c1e73d2
remove TODO - doesn't seem necessary
spang 9081d43
use functional declaration for list query params to support from and in
spang 52f2058
message update requests don't have params
spang 5b7125e
reuse EmailName class from events
spang c413184
add type for MessageHeader
spang 8f8146f
fix imports
spang 378dc7d
don't use nonexistent class
spang e677a7a
fix import
spang c47022b
query params should be optional on message find
spang 63cf181
query params should be optional on message update & delete
spang File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
from dataclasses import dataclass, field | ||
from dataclasses_json import dataclass_json, config | ||
from typing import List, Literal, Optional, Dict, Any | ||
from typing_extensions import TypedDict, NotRequired, get_type_hints | ||
from datetime import datetime | ||
|
||
from nylas.models.list_query_params import ListQueryParams | ||
from nylas.models.events import EmailName | ||
|
||
|
||
Fields = Literal["standard", "include_headers"] | ||
""" Literal representing which headers to include with a message. """ | ||
|
||
|
||
@dataclass_json | ||
@dataclass | ||
class MessageHeader: | ||
""" | ||
A message header. | ||
|
||
Attributes: | ||
name: The header name. | ||
value: The header value. | ||
""" | ||
|
||
name: str | ||
value: str | ||
|
||
|
||
@dataclass_json | ||
@dataclass | ||
class Attachment: | ||
""" | ||
An attachment on a message. | ||
|
||
Attributes: | ||
id: Globally unique object identifier. | ||
size: Size of the attachment in bytes. | ||
filename: Name of the attachment. | ||
content_type: MIME type of the attachment. | ||
""" | ||
|
||
id: str | ||
size: int | ||
filename: Optional[str] = None | ||
content_type: Optional[str] = None | ||
|
||
|
||
@dataclass_json | ||
@dataclass | ||
class Message: | ||
""" | ||
A Message object. | ||
|
||
Attributes: | ||
id: Globally unique object identifier. | ||
grant_id: The grant that this message belongs to. | ||
thread_id: The thread that this message belongs to. | ||
subject: The subject of the message. | ||
from_: The sender of the message. | ||
to: The recipients of the message. | ||
cc: The CC recipients of the message. | ||
bcc: The BCC recipients of the message. | ||
reply_to: The reply-to recipients of the message. | ||
date: The date the message was received. | ||
unread: Whether the message is unread. | ||
starred: Whether the message is starred. | ||
snippet: A snippet of the message body. | ||
body: The body of the message. | ||
attachments: The attachments on the message. | ||
folders: The folders that the message is in. | ||
headers: The headers of the message. | ||
""" | ||
|
||
id: str | ||
grant_id: str | ||
thread_id: str | ||
subject: str | ||
|
||
from_: List[EmailName] = field(metadata=config(field_name="from")) | ||
to: List[EmailName] | ||
|
||
date: datetime | ||
|
||
unread: bool | ||
starred: bool | ||
|
||
snippet: str | ||
body: str | ||
|
||
bcc: Optional[List[EmailName]] = None | ||
cc: Optional[List[EmailName]] = None | ||
reply_to: Optional[List[EmailName]] = None | ||
attachments: Optional[List[Attachment]] = None | ||
folders: Optional[List[str]] = None | ||
headers: Optional[List[MessageHeader]] = None | ||
|
||
|
||
# Need to use Functional typed dicts because "from" and "in" are Python | ||
# keywords, and can't be declared using the declarative syntax | ||
ListMessagesQueryParams = TypedDict( | ||
"ListMessagesQueryParams", | ||
{ | ||
**get_type_hints(ListQueryParams), # Inherit fields from ListQueryParams | ||
"subject": NotRequired[str], | ||
"any_email": NotRequired[str], | ||
"from": NotRequired[str], | ||
"to": NotRequired[str], | ||
"cc": NotRequired[str], | ||
"bcc": NotRequired[str], | ||
"in": NotRequired[str], | ||
"unread": NotRequired[bool], | ||
"starred": NotRequired[bool], | ||
"thread_id": NotRequired[str], | ||
"received_before": NotRequired[int], | ||
"received_after": NotRequired[int], | ||
"has_attachment": NotRequired[bool], | ||
"fields": NotRequired[Fields], | ||
"search_query_native": NotRequired[str], | ||
}, | ||
) | ||
""" | ||
Query parameters for listing messages. | ||
|
||
Attributes: | ||
subject: Return messages with matching subject. | ||
any_email: Return messages that have been sent or received by this comma-separated list of email addresses. | ||
from: Return messages sent from this email address. | ||
to: Return messages sent to this email address. | ||
cc: Return messages cc'd to this email address. | ||
bcc: Return messages bcc'd to this email address. | ||
in: Return messages in this specific folder or label, specified by ID. | ||
unread: Filter messages by unread status. | ||
starred: Filter messages by starred status. | ||
thread_id: Filter messages by thread_id. | ||
received_before: Return messages with received dates before received_before. | ||
received_after: Return messages with received dates after received_after. | ||
has_attachment: Filter messages by whether they have an attachment. | ||
fields: Specify "include_headers" to include headers in the response. "standard" is the default. | ||
search_query_native: A native provider search query for Google or Microsoft. | ||
limit (NotRequired[int]): The maximum number of objects to return. | ||
This field defaults to 50. The maximum allowed value is 200. | ||
page_token (NotRequired[str]): An identifier that specifies which page of data to return. | ||
This value should be taken from a ListResponse object's next_cursor parameter. | ||
""" | ||
|
||
|
||
class FindMessageQueryParams(TypedDict): | ||
|
||
"""Query parameters for finding a message. | ||
|
||
Attributes: | ||
fields: Specify "include_headers" to include headers in the response. "standard" is the default. | ||
""" | ||
|
||
fields: NotRequired[Fields] | ||
|
||
|
||
class UpdateMessageRequest(TypedDict): | ||
|
||
""" | ||
Request payload for updating a message. | ||
|
||
Attributes: | ||
starred: The message's starred status | ||
unread: The message's unread status | ||
folders: The message's folders | ||
metadata: A list of key-value pairs storing additional data | ||
""" | ||
|
||
unread: NotRequired[bool] | ||
starred: NotRequired[bool] | ||
folder: NotRequired[List[str]] | ||
metadata: NotRequired[Dict[str, Any]] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
from typing import Dict, Optional | ||
from nylas.handler.api_resources import ( | ||
ListableApiResource, | ||
FindableApiResource, | ||
UpdatableApiResource, | ||
DestroyableApiResource, | ||
) | ||
from nylas.models.messages import ( | ||
Message, | ||
ListMessagesQueryParams, | ||
FindMessageQueryParams, | ||
UpdateMessageRequest, | ||
) | ||
from nylas.models.response import Response, ListResponse, DeleteResponse | ||
|
||
|
||
class Messages( | ||
ListableApiResource, | ||
FindableApiResource, | ||
UpdatableApiResource, | ||
DestroyableApiResource, | ||
): | ||
def list( | ||
self, identifier: str, query_params: ListMessagesQueryParams | ||
) -> ListResponse[Message]: | ||
""" | ||
Return all Messages. | ||
|
||
Args: | ||
identifier: The identifier of the grant to get messages for. | ||
query_params: The query parameters to filter messages by. | ||
|
||
Returns: | ||
A list of Messages. | ||
""" | ||
return super(Messages, self).list( | ||
path=f"/v3/grants/{identifier}/messages", | ||
response_type=Message, | ||
query_params=query_params, | ||
) | ||
|
||
def find( | ||
self, | ||
identifier: str, | ||
message_id: str, | ||
query_params: Optional[FindMessageQueryParams] = None, | ||
) -> Response[Message]: | ||
""" | ||
Return a Message. | ||
|
||
Args: | ||
identifier: The identifier of the grant to get the message for. | ||
message_id: The identifier of the message to get. | ||
query_params: The query parameters to include in the request. | ||
|
||
Returns: | ||
The requested Message. | ||
""" | ||
return super(Messages, self).find( | ||
path=f"/v3/grants/{identifier}/messages/{message_id}", | ||
response_type=Message, | ||
query_params=query_params, | ||
) | ||
|
||
def update( | ||
self, | ||
identifier: str, | ||
message_id: str, | ||
request_body: UpdateMessageRequest, | ||
query_params: Optional[Dict] = None, | ||
) -> Response[Message]: | ||
""" | ||
Update a Message. | ||
|
||
Args: | ||
identifier: The identifier of the grant to update the message for. | ||
message_id: The identifier of the message to update. | ||
request_body: The request body to update the message with. | ||
query_params: The query parameters to include in the request. | ||
|
||
Returns: | ||
The updated Message. | ||
""" | ||
return super(Messages, self).update( | ||
path=f"/v3/grants/{identifier}/messages/{message_id}", | ||
response_type=Message, | ||
request_body=request_body, | ||
query_params=query_params, | ||
) | ||
|
||
def destroy( | ||
self, identifier: str, message_id: str, query_params: Optional[Dict] = None | ||
) -> DeleteResponse: | ||
""" | ||
Delete a Message. | ||
|
||
Args: | ||
identifier: The identifier of the grant to delete the message for. | ||
message_id: The identifier of the message to delete. | ||
query_params: The query parameters to include in the request. | ||
|
||
Returns: | ||
The deletion response. | ||
""" | ||
return super(Messages, self).destroy( | ||
path=f"/v3/grants/{identifier}/messages/{message_id}", | ||
query_params=query_params, | ||
) |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI, I have no idea if this docstring will end up in the autogenerated docs. Couldn't figure out any way to include a docstring on a functionally declared TypedDict.