Skip to content

Commit 9701484

Browse files
authored
feat: Added support for select query parameter to optimize API response size (#407)
* feat: add support for select query parameter to optimize API response size * fix: update events.py
1 parent 807d3b7 commit 9701484

21 files changed

+699
-49
lines changed

.coveragerc

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
11
[run]
22
source = nylas
3-
omit = tests/*
3+
omit =
4+
tests/*
5+
examples/*

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
nylas-python Changelog
22
======================
33

4+
Unreleased
5+
----------------
6+
* Added support for `select` query parameter in list calendars, list events, and list messages.
7+
48
v6.6.0
59
----------------
610
* Added response headers to all responses from the Nylas API
@@ -27,7 +31,6 @@ v6.3.1
2731
* Added Folder Webhooks
2832
* Removed use of TestCommand
2933

30-
3134
v6.3.0
3235
----------------
3336
* Added Folder query param support

examples/select_param_demo/README.md

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Select Parameter Demo
2+
3+
This example demonstrates the usage of the `select` query parameter across different Nylas resources. The `select` parameter allows you to specify which fields you want to receive in the API response, helping to optimize your API calls by reducing the amount of data transferred.
4+
5+
## Features Demonstrated
6+
7+
1. **Backwards Compatibility**: Shows that existing code that doesn't use the `select` parameter continues to work as expected, receiving all fields.
8+
2. **Field Selection**: Demonstrates how to use the `select` parameter to request only specific fields for better performance.
9+
3. **Multiple Resources**: Shows the `select` parameter working across different resources:
10+
- Messages
11+
- Calendars
12+
- Events
13+
- Drafts
14+
- Contacts
15+
16+
## Setup
17+
18+
1. Create a `.env` file in the root directory with your Nylas API credentials:
19+
```
20+
NYLAS_API_KEY=your_api_key_here
21+
```
22+
23+
2. Install the required dependencies:
24+
```bash
25+
pip install nylas python-dotenv
26+
```
27+
28+
## Running the Example
29+
30+
Run the example script:
31+
```bash
32+
python select_param_example.py
33+
```
34+
35+
The script will demonstrate both the traditional way of fetching all fields and the new selective field fetching for each resource type.
36+
37+
## Example Output
38+
39+
The script will show output similar to this for each resource:
40+
```
41+
=== Messages Resource ===
42+
43+
Fetching messages (all fields):
44+
Full message - Subject: Example Subject, ID: abc123...
45+
46+
Fetching messages with select (only id and subject):
47+
Minimal message - Subject: Example Subject, ID: abc123...
48+
```
49+
50+
## Benefits of Using Select
51+
52+
1. **Reduced Data Transfer**: By selecting only the fields you need, you reduce the amount of data transferred over the network.
53+
2. **Improved Performance**: Smaller payloads mean faster API responses and less processing time.
54+
3. **Bandwidth Optimization**: Especially useful in mobile applications or when dealing with limited bandwidth.
55+
56+
## Available Fields
57+
58+
The fields available for selection vary by resource type. Refer to the [Nylas API documentation](https://developer.nylas.com/) for a complete list of available fields for each resource type.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Nylas SDK Example: Using Select Parameters
4+
5+
This example demonstrates how to use the 'select' query parameter across different Nylas resources
6+
to optimize API response size and performance by requesting only specific fields.
7+
8+
Required Environment Variables:
9+
NYLAS_API_KEY: Your Nylas API key
10+
NYLAS_GRANT_ID: Your Nylas grant ID
11+
12+
Usage:
13+
First, install the SDK in development mode:
14+
cd /path/to/nylas-python
15+
pip install -e .
16+
17+
Then set environment variables and run:
18+
export NYLAS_API_KEY="your_api_key"
19+
export NYLAS_GRANT_ID="your_grant_id"
20+
python examples/select_param_demo/select_param_example.py
21+
"""
22+
23+
import os
24+
import sys
25+
import json
26+
from nylas import Client
27+
28+
29+
def get_env_or_exit(var_name: str) -> str:
30+
"""Get an environment variable or exit if not found."""
31+
value = os.getenv(var_name)
32+
if not value:
33+
print(f"Error: {var_name} environment variable is required")
34+
sys.exit(1)
35+
return value
36+
37+
38+
def print_data(data: list, title: str) -> None:
39+
"""Pretty print the data with a title."""
40+
print(f"\n{title}:")
41+
for item in data:
42+
# Convert to dict and pretty print
43+
item_dict = item.to_dict()
44+
print(json.dumps(item_dict, indent=2))
45+
46+
47+
def demonstrate_messages(client: Client, grant_id: str) -> None:
48+
"""Demonstrate select parameter usage with Messages resource."""
49+
print("\n=== Messages Resource ===")
50+
51+
# Backwards compatibility - fetch all fields
52+
print("\nFetching messages (all fields):")
53+
messages = client.messages.list(identifier=grant_id, query_params={"limit": 2})
54+
print_data(messages.data, "Full message data (all fields)")
55+
56+
# Using select parameter - fetch only specific fields
57+
print("\nFetching messages with select (only id and subject):")
58+
messages = client.messages.list(
59+
identifier=grant_id,
60+
query_params={"limit": 2, "select": "id,subject"}
61+
)
62+
print_data(messages.data, "Minimal message data (only selected fields)")
63+
64+
65+
def demonstrate_calendars(client: Client, grant_id: str) -> None:
66+
"""Demonstrate select parameter usage with Calendars resource."""
67+
print("\n=== Calendars Resource ===")
68+
69+
# Backwards compatibility - fetch all fields
70+
print("\nFetching calendars (all fields):")
71+
calendars = client.calendars.list(identifier=grant_id, query_params={"limit": 2})
72+
print_data(calendars.data, "Full calendar data (all fields)")
73+
74+
# Using select parameter - fetch only specific fields
75+
print("\nFetching calendars with select (only id and name):")
76+
calendars = client.calendars.list(
77+
identifier=grant_id,
78+
query_params={"limit": 2, "select": "id,name"}
79+
)
80+
print_data(calendars.data, "Minimal calendar data (only selected fields)")
81+
82+
83+
def demonstrate_events(client: Client, grant_id: str) -> None:
84+
"""Demonstrate select parameter usage with Events resource."""
85+
print("\n=== Events Resource ===")
86+
87+
# First, get a calendar ID
88+
print("\nFetching first calendar to use for events...")
89+
calendars = client.calendars.list(identifier=grant_id, query_params={"limit": 1})
90+
if not calendars.data:
91+
print("No calendars found. Skipping events demonstration.")
92+
return
93+
94+
calendar_id = calendars.data[0].id
95+
print(f"Using calendar: {calendars.data[0].name} (ID: {calendar_id})")
96+
97+
# Backwards compatibility - fetch all fields
98+
print("\nFetching events (all fields):")
99+
events = client.events.list(
100+
identifier=grant_id,
101+
query_params={"limit": 2, "calendar_id": calendar_id}
102+
)
103+
print_data(events.data, "Full event data (all fields)")
104+
105+
# Using select parameter - fetch only specific fields
106+
print("\nFetching events with select (only id and title):")
107+
events = client.events.list(
108+
identifier=grant_id,
109+
query_params={
110+
"limit": 2,
111+
"calendar_id": calendar_id,
112+
"select": "id,title"
113+
}
114+
)
115+
print_data(events.data, "Minimal event data (only selected fields)")
116+
117+
118+
def demonstrate_drafts(client: Client, grant_id: str) -> None:
119+
"""Demonstrate select parameter usage with Drafts resource."""
120+
print("\n=== Drafts Resource ===")
121+
122+
# Backwards compatibility - fetch all fields
123+
print("\nFetching drafts (all fields):")
124+
drafts = client.drafts.list(identifier=grant_id, query_params={"limit": 2})
125+
print_data(drafts.data, "Full draft data (all fields)")
126+
127+
# Using select parameter - fetch only specific fields
128+
print("\nFetching drafts with select (only id and subject):")
129+
drafts = client.drafts.list(
130+
identifier=grant_id,
131+
query_params={"limit": 2, "select": "id,subject"}
132+
)
133+
print_data(drafts.data, "Minimal draft data (only selected fields)")
134+
135+
136+
def demonstrate_contacts(client: Client, grant_id: str) -> None:
137+
"""Demonstrate select parameter usage with Contacts resource."""
138+
print("\n=== Contacts Resource ===")
139+
140+
# Backwards compatibility - fetch all fields
141+
print("\nFetching contacts (all fields):")
142+
contacts = client.contacts.list(identifier=grant_id, query_params={"limit": 2})
143+
print_data(contacts.data, "Full contact data (all fields)")
144+
145+
# Using select parameter - fetch only specific fields
146+
print("\nFetching contacts with select (only id, grant_id, and given_name):")
147+
contacts = client.contacts.list(
148+
identifier=grant_id,
149+
query_params={"limit": 2, "select": "id,grant_id,given_name"}
150+
)
151+
print_data(contacts.data, "Minimal contact data (only selected fields)")
152+
153+
154+
def main():
155+
"""Main function demonstrating select parameter usage across resources."""
156+
# Get required environment variables
157+
api_key = get_env_or_exit("NYLAS_API_KEY")
158+
grant_id = get_env_or_exit("NYLAS_GRANT_ID")
159+
160+
# Initialize Nylas client
161+
client = Client(
162+
api_key=api_key,
163+
)
164+
165+
print("\nDemonstrating Select Parameter Usage")
166+
print("===================================")
167+
print("This shows both backwards compatibility and selective field fetching")
168+
169+
# Demonstrate select parameter across different resources
170+
demonstrate_messages(client, grant_id)
171+
demonstrate_calendars(client, grant_id)
172+
demonstrate_events(client, grant_id)
173+
demonstrate_drafts(client, grant_id)
174+
demonstrate_contacts(client, grant_id)
175+
176+
print("\nExample completed!")
177+
178+
179+
if __name__ == "__main__":
180+
main()

nylas/models/calendars.py

+14
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,25 @@ class ListCalendarsQueryParams(ListQueryParams):
5757
page_token (NotRequired[str]): An identifier that specifies which page of data to return.
5858
This value should be taken from a ListResponse object's next_cursor parameter.
5959
metadata_pair: Pass in your metadata key-value pair to search for metadata.
60+
select (NotRequired[str]): Comma-separated list of fields to return in the response.
61+
This allows you to receive only the portion of object data that you're interested in.
6062
"""
6163

6264
metadata_pair: NotRequired[Dict[str, str]]
6365

6466

67+
class FindCalendarQueryParams(TypedDict):
68+
"""
69+
Interface of the query parameters for finding a calendar.
70+
71+
Attributes:
72+
select: Comma-separated list of fields to return in the response.
73+
This allows you to receive only the portion of object data that you're interested in.
74+
"""
75+
76+
select: NotRequired[str]
77+
78+
6579
class CreateCalendarRequest(TypedDict):
6680
"""
6781
Interface of a Nylas create calendar request

nylas/models/contacts.py

+22-21
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,20 @@ class Contact:
173173
groups: Optional[List[ContactGroupId]] = None
174174

175175

176+
class FindContactQueryParams(TypedDict):
177+
"""
178+
The available query parameters for finding a contact.
179+
Attributes:
180+
profile_picture: If true and picture_url is present, the response includes a Base64 binary data blob that
181+
you can use to view information as an image file.
182+
select: Comma-separated list of fields to return in the response.
183+
This allows you to receive only the portion of object data that you're interested in.
184+
"""
185+
186+
profile_picture: NotRequired[bool]
187+
select: NotRequired[str]
188+
189+
176190
class WriteablePhoneNumber(TypedDict):
177191
"""
178192
A phone number for a contact.
@@ -316,21 +330,20 @@ class CreateContactRequest(TypedDict):
316330

317331
class ListContactsQueryParams(ListQueryParams):
318332
"""
319-
Interface of the query parameters for listing calendars.
333+
Interface representing the query parameters for listing contacts.
320334
321335
Attributes:
336+
email: Return contacts with matching email address.
337+
phone_number: Return contacts with matching phone number.
338+
source: Return contacts from a specific source.
339+
group: Return contacts from a specific group.
340+
recurse: Return contacts from all sub-groups of the specified group.
341+
select (NotRequired[str]): Comma-separated list of fields to return in the response.
342+
This allows you to receive only the portion of object data that you're interested in.
322343
limit (NotRequired[int]): The maximum number of objects to return.
323344
This field defaults to 50. The maximum allowed value is 200.
324345
page_token (NotRequired[str]): An identifier that specifies which page of data to return.
325346
This value should be taken from a ListResponse object's next_cursor parameter.
326-
email: Returns the contacts matching the exact contact's email.
327-
phone_number: Returns the contacts matching the contact's exact phone number
328-
source: Returns the contacts matching from the address book or auto-generated contacts from emails.
329-
For example of contacts only from the address book: /contacts?source=address_bookor
330-
for only autogenerated contacts:/contacts?source=inbox`
331-
group: Returns the contacts belonging to the Contact Group matching this ID
332-
recurse: When set to true, returns the contacts also within the specified Contact Group subgroups,
333-
if the group parameter is set.
334347
"""
335348

336349
email: NotRequired[str]
@@ -340,18 +353,6 @@ class ListContactsQueryParams(ListQueryParams):
340353
recurse: NotRequired[bool]
341354

342355

343-
class FindContactQueryParams(TypedDict):
344-
"""
345-
The available query parameters for finding a contact.
346-
347-
Attributes:
348-
profile_picture: If true and picture_url is present, the response includes a Base64 binary data blob that
349-
you can use to view information as an image file.
350-
"""
351-
352-
profile_picture: NotRequired[bool]
353-
354-
355356
class GroupType(str, Enum):
356357
"""Enum representing the different types of contact groups."""
357358

nylas/models/drafts.py

+12
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ class CreateDraftRequest(TypedDict):
149149
"""
150150

151151

152+
class FindDraftQueryParams(TypedDict):
153+
"""
154+
Query parameters for finding a draft.
155+
156+
Attributes:
157+
select: Comma-separated list of fields to return in the response.
158+
This allows you to receive only the portion of object data that you're interested in.
159+
"""
160+
161+
select: NotRequired[str]
162+
163+
152164
class SendMessageRequest(CreateDraftRequest):
153165
"""
154166
A request to send a message.

0 commit comments

Comments
 (0)