Skip to content

Releases: nylas/nylas-python

v5.8.0

14 Apr 21:39
Compare
Choose a tag to compare

This new release of the Nylas Python SDK brings a few changes.

Release Notes

Added

  • Add support for getting the number of queried objects (count view)

Changed

  • Improved usage of read only fields in models (fixes #212)

Fixed

  • Fix Calendar availability functions not using the correct authentication method

Using New Features

Getting the number of queried objects (count view)

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

total_contacts = nylas.contacts.count()

# We also support filtering in conjunction with count
emails_from_support = nylas.messages.where(from_="[email protected]").count()

v5.7.0

31 Mar 21:12
Compare
Choose a tag to compare

This new release of the Nylas Python SDK a couple of new features and enhancements.

Release Notes

Added

  • Add Outbox support
  • Add support for new (beta) Integrations authentication (Integrations API, Grants API, Hosted Authentication for Integrations)
  • Add support for limit and offset for message/thread search
  • Add authentication_type field to Account

Changed

  • Bump supported API version to v2.5

Fixed

  • Fix Draft not sending metadata (#205)

Using New Features

Outbox

To send a new message through the outbox:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

# Create a draft
draft = api_client.drafts.create()
draft.subject = "With Love, from Nylas"
draft.to = [{"email": "[email protected]", "name": "Me"}]
draft.body = "This email was sent using the Nylas email API. Visit https://nylas.com for details."

# Set the outbox-specific parameters
tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
day_after = tomorrow + datetime.timedelta(days=1)

# Send the outbox message
job_status = nylas.outbox.send(draft, tomorrow, retry_limit_datetime=day_after)

To update an outbox message after sending it

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

# Modify the message
draft = nylas.drafts.get('{id}')
draft.subject = "With Love, from Nylas"

# Set the outbox-specific parameters
tomorrow = datetime.datetime.today() + datetime.timedelta(days=1)
day_after = tomorrow + datetime.timedelta(days=1)

# Update the outbox message
job_status = nylas.outbox.update("job-status-id", draft=draft, send_at=tomorrow, retry_limit_datetime=day_after)

To delete an outbox job

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

nylas.outbox.delete("job-status-id")

We also support SendGrid operations. To get the authentication and verification status

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

verification = nylas.outbox.send_grid_verification_status()
verification.domain_verified
verification.sender_verified

To delete a SendGrid user:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

nylas.outbox.delete_send_grid_sub_user("[email protected]")

Integration Authentication (Beta)

Integrations API

To list all integrations:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

all_integrations = nylas.authentication.integrations.list()

To get an integration for a specific OAuth Provider:

from nylas import APIClient
from nylas.client.authentication_models import Authentication
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

integration = nylas.authentication.integrations.get(Authentication.Provider.ZOOM)

To create a new integration (we will use Zoom for example):

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

integration = nylas.authentication.integrations.create()
integration.name("My Zoom Intrgration")
integration.set_client_id("zoom.client.id")
integration.set_client_secret("zoom.client.secret")
integration.redirect_uris = ["https://www.nylas.com"]
integration.expires_in(1209600)
integration.save()

To update an existing integration:

from nylas import APIClient
from nylas.client.authentication_models import Authentication
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

zoom_integration = nylas.authentication.integrations.get(Authentication.Provider.ZOOM)
zoom_integration.name = "Updated name"
zoom_integration.save()

To delete an existing integration for a specific OAuth provider:

from nylas import APIClient
from nylas.client.authentication_models import Authentication
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

nylas.authentication.integrations.delete(Authentication.Provider.ZOOM);

Grants

To list all grants:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

all_grants = nylas.authentication.grants.list()

To get a specific grant:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

grant = nylas.authentication.grants.get("grant-id")

To create a new grant (we will use Zoom for example):

from nylas import APIClient
from nylas.client.authentication_models import Authentication
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

grant = nylas.authentication.grants.create()
grant.provider = Authentication.Provider.ZOOM
grant.settings = {"refresh_token": "zoom_refresh_token"}
grant.state = "test_state"
grant.scope = ["meeting:write"]
grant.metadata = {"sdk": "python sdk"}
grant.save()

To update an existing grant:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

grant = nylas.authentication.grants.get("grant-id")
grant.metadata = {"sdk": "python sdk"}
grant.save()

To delete an existing grant:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

nylas.authentication.grants.delete("grant_id");

To trigger a re-sync on a grant:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

resyced_grant = nylas.authentication.grants.on-demand-sync("grant_id",  sync_from=60);

Hosted Authentication for Authentication

To begin the hosted authentication process and get a login url:

from nylas import APIClient
from nylas.client.authentication_models import Authentication
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

login_info = nylas.authentication.hosted_authentication(
  provider=Authentication.Provider.ZOOM,
  redirect_uri="https://www.nylas.com",
  settings={"refresh_token": "zoom_refresh_token"},
  scope=["meeting:write"],
  metadata={"sdk": "python sdk"},
  login_hint="[email protected]",
  state="my-state",
  expires_in=43200
)

v5.6.0

15 Feb 15:37
Compare
Choose a tag to compare

This new release of the Nylas Python SDK a couple of new features and enhancements.

New Features

  • Add Delta support
  • Add Webhook support (#193)

Enhancements

  • Omit None values from resulting as_json() object
  • Enable Nylas API v2.4 support

Usage

Delta

To get the latest cursor:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

cursor = nylas.deltas.latest_cursor()

To return a set of delta cursors since a specific cursor:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

delta_response = nylas.deltas.since("{CURSOR}")

# The returned type is of Deltas
cursor_start = delta_response.cursor_start
cursor_end = delta_response.cursor_end
list_of_deltas = delta_response.deltas

# Deltas.deltas contains a list of Delta objects
delta = list_of_deltas[0]
delta_cursor = delta.cursor
delta_event = delta.event
delta_id = delta.id
delta_object = delta.object

# The enclosed Delta.attributes instantiates the object provided in the Delta (Contact, File, etc.)
delta_attributes = delta.attributes

# You can also pass in other optional arguments:
# view: string - This type of view to return within the delta objects
# include_types: string[] | string - The list of types to include in the query ('file', 'event', etc.)
# exclude_types: string[] | string - The list of types to exclude in the query ('file', 'event', etc.)

nylas.deltas.since(cursor, view="expanded", include_types=["event", "file"])

To stream for delta cursors since a specific cursor:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

# By default, the streaming function will listen indefinitely until the connection drops
# and upon reaching the end it will return an array of delta objects captured

streamed_deltas = nylas.deltas.stream(cursor)

# Optionally, you can pass in a reference to a function that would be called on every Delta

def on_delta_received(delta):
    print(delta)

nylas.deltas.stream(cursor, callback=on_delta_received)

# Furthermore, you can pass in an argument for timeout if you want to cut off the stream after a certain number of seconds

nylas.deltas.stream(cursor, callback=on_delta_received, timeout=180)

# You can also pass in other optional arguments:
# view: string - This type of view to return within the delta objects
# include_types: string[] | string - The list of types to include in the query ('file', 'event', etc.)
# exclude_types: string[] | string - The list of types to exclude in the query ('file', 'event', etc.)

nylas.deltas.stream(cursor, callback=on_delta_received, view="expanded", include_types=["event", "file"])

To long-poll for delta cursors since a specific cursor:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

# By default, the streaming function will listen until until the timeout is reached
# and upon reaching the end it will return a Deltas object

longpoll_deltas = nylas.deltas.longpoll(cursor, timeout=30) # timeout is in seconds

# Optionally, you can pass in a reference to a function that would be called when the Deltas response is returned

def on_deltas_received(deltas):
    print(deltas)

nylas.deltas.longpoll(cursor, callback=on_deltas_received)

# You can also pass in other optional arguments:
# view: string - This type of view to return within the delta objects
# include_types: string[] | string - The list of types to include in the query ('file', 'event', etc.)
# exclude_types: string[] | string - The list of types to exclude in the query ('file', 'event', etc.)

nylas.deltas.longpoll(cursor, callback=on_delta_received, view="expanded", include_types=["event", "file"])

Webhooks

To create a new webhook:

webhook = nylas.webhooks.create()
webhook.callback_url = "https://your-server.com/webhook"
webhook.triggers = ["message.created"]
webhook.state = "active"
webhook.save()

To get all webhooks:

webhooks = nylas.webhooks.all()

To get a specific webhook:

webhook = nylas.webhooks.get("{WEBHOOK_ID}")

To update a component:

webhook = nylas.webhooks.get("{WEBHOOK_ID}")
webhook.state = "inactive"
webhook.save()

To delete a component:

nylas.webhooks.delete("{WEBHOOK_ID}")

There are also two helper enums provided for Webhooks, Trigger and State:

# The available Webhook triggers:
Webhook.Trigger.ACCOUNT_CONNECTED = "account.connected"
Webhook.Trigger.ACCOUNT_RUNNING = "account.running"
Webhook.Trigger.ACCOUNT_STOPPED = "account.stopped"
Webhook.Trigger.ACCOUNT_INVALID = "account.invalid"
Webhook.Trigger.ACCOUNT_SYNC_ERROR = "account.sync_error"
Webhook.Trigger.MESSAGE_CREATED = "message.created"
Webhook.Trigger.MESSAGE_OPENED = "message.opened"
Webhook.Trigger.MESSAGE_UPDATED = "message.updated"
Webhook.Trigger.MESSAGE_LINK_CLICKED = "message.link_clicked"
Webhook.Trigger.THREAD_REPLIED = "thread.replied"
Webhook.Trigger.CONTACT_CREATED = "contact.created"
Webhook.Trigger.CONTACT_UPDATED = "contact.updated"
Webhook.Trigger.CONTACT_DELETED = "contact.deleted"
Webhook.Trigger.CALENDAR_CREATED = "calendar.created"
Webhook.Trigger.CALENDAR_UPDATED = "calendar.updated"
Webhook.Trigger.CALENDAR_DELETED = "calendar.deleted"
Webhook.Trigger.EVENT_CREATED = "event.created"
Webhook.Trigger.EVENT_UPDATED = "event.updated"
Webhook.Trigger.EVENT_DELETED = "event.deleted"
Webhook.Trigger.JOB_SUCCESSFUL = "job.successful"
Webhook.Trigger.JOB_FAILED = "job.failed"

# The available Webhook states:
Webhook.State.ACTIVE = "active"
Webhook.State.INACTIVE = "inactive"

v5.5.1

10 Feb 17:58
Compare
Choose a tag to compare

This patch release of the Nylas Python SDK contains two minor enhancements.

Enhancements

  • Add validation for send_authorization (#194)
  • Fix native-authentication-gmail example app (#192)

v5.5.0

01 Feb 18:51
Compare
Choose a tag to compare

This new release of the Nylas Python SDK a new feature as well as an enhancement.

New Features

  • Add support for Event to ICS

Enhancements

  • Enable full payload response for exchanging the token for code

Usage

Generate ICS from Event

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)
example_event = nylas.events.get('{id}')

# Generate an ICS from an event
ics = example_event.generate_ics()

# You can also pass ICS Options for more configuration
ics = example_event.generate_ics(
  ical_uid="test_uuid",
  method="add",
  prodid="test_prodid"
)

Exchange Token for Code (full payload)

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

ACCESS_TOKEN = nylas.send_authorization('{code_from_nylas}')

v5.4.2

13 Jan 22:23
Compare
Choose a tag to compare

This patch release of the Nylas Python SDK contains a single minor enhancement.

Enhancements

  • Add missing source field in Contact class

v5.4.1

23 Dec 18:48
Compare
Choose a tag to compare

This patch release of the Nylas Python SDK comtains as a couple of enhancements.

Enhancements

  • Improved support for Application Details
  • Fix issue where keyword arguments calling _update_resource were not correctly resolving to URL params

Usage

To get application details:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET
)

app_data = nylas.application_details()

To update application details:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET
)

updated_app_data = nylas.update_application_details(
    application_name="New Name",
    icon_url="https://myurl.com/icon.png",
    redirect_uris=["https://redirect.com"],
)

To delete an account:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET
)

nylas.accounts.delete("{account_id}")

v5.4.0

16 Dec 19:05
Compare
Choose a tag to compare

This new release of the Nylas Python SDK a new feature as well as a couple of enhancements.

New Features

  • Add job status support

Enhancements

  • Add is_primary field to Calendar
  • Fix bug where updating an Event results in an API error

Usage

Job Status

To view all Job statuses

job_statuses = nylas.job_statuses.all()

To view a specific Job status

job_status = nylas.job_statuses.get("JOB_STATUS_ID")

To get a boolean value representing Job status success/failure

job_status = nylas.job_statuses.get("JOB_STATUS_ID")
job_status.is_successful()

v5.3.0

26 Nov 18:47
Compare
Choose a tag to compare

This new release of the Nylas Python SDK brings a slew of new features with support to many new Nylas APIs as well as new features to enhance existing models.

New Features

  • Add support for Scheduler API
  • Add support for Event notifications
  • Add support for Component CRUD
  • Add metadata support for Calendar, Message and Account

Enhancements

  • Improve error details returned from the API

Usage

Scheduler API

To create a new Scheduler page:

scheduler = nylas.scheduler.create()
scheduler.access_tokens = ["ACCESS_TOKEN"]
scheduler.name = "Python SDK Example"
scheduler.slug = "py_example_1"
scheduler.save()

To return all Scheduler pages:

scheduler_list = nylas.scheduler.all()

To return a single Scheduler page:

scheduler = nylas.scheduler.get('SCHEDULER_ID')

To update a Scheduler page:

scheduler = nylas.scheduler.get('SCHEDULER_ID')
scheduler.name = "Updated page name"
scheduler.save()

To delete a Scheduler page:

nylas.scheduler.delete('SCHEDULER_ID')

To get available calendars for a Scheduler page:

scheduler = nylas.scheduler.get('SCHEDULER_ID')
calendars = scheduler.get_available_calendars()

To upload an image:

scheduler = nylas.scheduler.get('SCHEDULER_ID')
scheduler.upload_image(content_type: "image/png", object_name: "test.png")

Checking Provider Availability

# Google Availability
google_availability = nylas.scheduler.get_google_availability()

# Office 365 Availability
o365_availability = nylas.scheduler.get_office_365_availability()

Get page information/configuration

page_config = nylas.scheduler.get_page_slug('slug')

Retrieve available time slots

available_timeslots = nylas.scheduler.get_available_time_slots('slug')

Book a time slot

slot = SchedulerTimeSlot.create(nylas)
slot.account_id = "test-account-id"
slot.calendar_id = "test-calendar-id"
slot.emails = ["[email protected]"]
slot.host_name = "Host"
slot.start = datetime.utcfromtimestamp(1636728347)
slot.end = datetime.utcfromtimestamp(1636731958)

timeslot_to_book = SchedulerBookingRequest.create(nylas)
timeslot_to_book.additional_values = {
    "test": "yes",
}
timeslot_to_book.email = "[email protected]"
timeslot_to_book.locale = "en_US"
timeslot_to_book.name = "Recipient Doe"
timeslot_to_book.timezone = "America/New_York"
timeslot_to_book.slot = slot

booking_confirmation = nylas.scheduler.book_time_slot("slug", timeslot_to_book)

Confirm a booking

booking_confirmation = nylas.scheduler.confirm_booking('slug', 'edit-hash');

Cancel a booking

nylas.scheduler.cancel_booking('slug', 'edit-hash', 'reason');

Event Notifications

To create a notification for an event:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

# Create a new event
event = nylas.events.create()

# Add notification details to the event
event.notifications = [
  {
    body: "Reminding you about our meeting.",
    minutes_before_event: 600,
    subject: "Test Event Notification",
    type: "email"
  },
  {
    type: "webhook",
    minutes_before_event: 600,
    url: "https://hooks.service.com/services/T01A03EEXDE/B01TBNH532R/HubIZu1zog4oYdFqQ8VUcuiW",
    payload: json.dumps({
      text: "Your reminder goes here!"
    })
  },
  {
    type: "sms",
    minutes_before_event: 60,
    message: "Test Event Notfication"
  }
]

To retrieve event notification details of an event:

# Get an event
event = nylas.events.get("EVENT_ID")

# Add notification details to the event
minutes_before_event = event.notifications[0].["minutes_before_event"]
type = event.notifications[0].["type"]
body = event.notifications[0].["body"]
url = event.notifications[0].["url"]
subject = event.notifications[0].["subject"]
payload = event.notifications[0].["payload"]
message = event.notifications[0].["message"]

To update an event with a notification:

# Get an event
event = nylas.events.get("EVENT_ID")

event.notifications = [{
    body: "Reminding you about our meeting.",
    minutes_before_event: 600,
    subject: "Test Event Notification",
    type: "email"
  }]
event.save()

To delete a notification from an event:

# Get an event
event = nylas.events.get("EVENT_ID")

event.notifications = []
event.save()

Component CRUD

To create a new component:

component = nylas.components.create()
component.name = "Python Component"
component.type = "agenda"
component.public_account_id = "ACCOUNT_PUBLIC_ID"
component.access_token = "ACCOUNT_ACCESS_TOKEN"
component.save()

To get all components:

components = nylas.components.all()

To get a specific component:

component = nylas.components.get("{COMPONENT_ID}")

To update a component:

component = nylas.components.get("{COMPONENT_ID}")
component.name = "Updated"
component.save()

To delete a component:

nylas.components.delete("{COMPONENT_ID}")

Expanded Metadata support

Adding Metadata to Calendar

calendar = nylas.calendars.create()
calendar.name = "My New Calendar"
calendar.description = "Description of my new calendar"
calendar.location = "Location description"
calendar.timezone = "America/Los_Angeles"
calendar.metadata = {
  "event_type": "gathering"
}
calendar.save()

# Or you can update a calendar with metadata

calendar = nylas.calendars.first()

calendar.metadata = {
  "event_type": "gathering"
}
calendar.save()

Query Calendars by Metadata

calendars = nylas.calendars.where(metadata_pair={event_type: "gathering"})

Adding Metadata to Message

message = nylas.messages.first()

message.metadata = {
  "test": "true"
}
message.save()

Adding Metadata to Account

account = api.accounts[0]

account.metadata = {
  "test": "true"
}
account.save()

Query Account by Metadata

accounts = api.accounts.where(metadata_key="test");

v5.2.0

24 Sep 20:50
Compare
Choose a tag to compare

This new release of the Nylas Python SDK brings a couple of critical fixes as well as enhancing support for Event Conference Sync with Auto Create Meetings (Private Beta) support as well as improving calendar availability support.

New Features

  • Add support for calendar consecutive availability
  • Add dynamic conferencing link creation support

Usage

Consecutive Availability

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

emails = [["[email protected]"], ["[email protected]", "[email protected]"]]
duration = 30
interval = 60
start_at = 1632236400
end_at = 1632240000
open_hours = api_client.open_hours(
    [
        "[email protected]",
        "[email protected]",
        "[email protected]",
        "[email protected]",
    ],
    [0],
    "America/Chicago",
    "10:00",
    "14:00",
)
free_busy = [
    {
        "email": "[email protected]",
        "time_slots": [
            {
                "object": "time_slot",
                "status": "busy",
                "start_time": 1632236400,
                "end_time": 1632240000,
            }
        ],
    }
]
api_client.consecutive_availability(
    emails,
    duration,
    interval,
    start_at,
    end_at,
    free_busy=free_busy,
    open_hours=open_hours,
)

Auto Create Meetings

To have Nylas autocreate the conference field for you, pass the autocreate object to the new event:

from nylas import APIClient
nylas = APIClient(
    CLIENT_ID,
    CLIENT_SECRET,
    ACCESS_TOKEN
)

#Create a new event
event = nylas.events.create()

# add conferencing details
event.conferencing = {
    "provider": "Zoom Meeting",
    "conferencing": {
        "autocreate": {
            "settings": {
                "password": "1234",
            },
        },
    },
}

A few notes and things to keep in mind:

  • Only one of details or autocreate can be present, and we have implemented client-side checking to enforce this rule
  • Autocreating conferencing data is an asynchronous operation on the server-side. The Event object returned will not have a conferencing field, but it should be available in a future get call once the conference is created on the backend. The initial Event object returned will have a jobStatusId value which can be used to check on the status of conference creation.
  • The settings object within the autocreate object maps to the settings the Nylas API will send to the conference provider for the conference creation. For example with Zoom the settings object maps to Zoom's Create a Meeting object.