Skip to content

Commit

Permalink
v6.0.0 (#341)
Browse files Browse the repository at this point in the history
# Description
This PR is a culmination of all the PRs that contained v6-related development, with formal support for the Nylas API v3. This release is essentially the same as the v6.0.0b9 release found on pypi. Please refer to the readme for a quick start guide on using the new SDK, as well as links to the upgrade doc as well as the SDK reference docs.

# Changelog
* **BREAKING CHANGE**: Python SDK v6 supports the Nylas API v3 exclusively, dropping support for any endpoints that are not available in v3
* **BREAKING CHANGE**: Drop support for Python < v3.8
* **BREAKING CHANGE**: Dropped the use of 'Collections' in favor of 'Resources'
* **BREAKING CHANGE**: Removed all REST calls from models and moved them directly into resources
* **BREAKING CHANGE**: Models no longer inherit from `dict` but instead either are a `dataclass` or inherit from `TypedDict`
* **BREAKING CHANGE**: Renamed the SDK entrypoint from `APIClient` to `Client`
* **REMOVED**: Local Webhook development support is removed due to incompatibility
* Rewrote the majority of SDK to be more intuitive, explicit, and efficient
* Created models for all API resources and endpoints, for all HTTP methods to reduce confusion on which fields are available for each endpoint
* Created error classes for the different API errors as well as SDK-specific errors

======================================================================================

* Python SDK Rewrite for API v3 (with Auth, Calendars, and Event support) (#262)

This PR re-writes the Python SDK to be less complex, more human readable, and more intuitive to use. The rewrite also enables support for API v3. The following changes have been made:
- Full rewrite of the SDK, including the HTTP Client
- Dropped support for Python 2.7 and any Python 3.x < 3.8
- Updated all the dependencies to the latest versions
- Support for communicating with API v3 and parsing the response schemas
- Full support for all auth-related methods for API v3
- Full CRUD support for Calendars and Events APIs in API v3

* Add models and typing to resources (#266)

This PR adds models for create and update models and adds typing to all the resources.

Also the following were done:
- Renamed the model package to models
- Cleaned up dependencies
- Add availability and webhook support
- Add generics support
- Change our mixin strategy

* Refactor Auth classes (#267)

This PR aligns the Python SDK to the other SDKs regarding Auth resource functions and models.

* Refactor Error Classes (#268)

This PR ensures the Python SDK has all the models and handling logic required for the different errors that may arise.

* Set up SDK Reference generation (#269)

This PR configures mkdocs to generate an SDK reference for the Python SDK.

* Python SDK v6 Documentation (#270)

This PR finalizes all the in-code documentation, updates the README.md file and adds an UPGRADE.md file.

* v6.0.0 beta 1 Release (#271)

This PR sets up for v6.0.0 beta 1 release.

* Fix API contract for Events (#272)

Fixes to the Event object

* Add None init for Optional fields (#273)

This PR addresses a bug that causes Event deserialization to break. This is because we should init all Optional fields to None.

* v6.0.0 beta 2 Release

* Fix bug when deserializing Union types (#275)

This PR adds in deserialization logic for the polyformic fields.

* Fix bug when deserializing delete response (#277)

For `.destroy()` method we are not using the correct model to deserialize the response to. We just discard it and use `Response` which results in a KeyError.

* v6.0.0 beta 3 Release (#278)

* Improve quickstart examples & documentation overview (#281)

This is everything that tripped me up getting started and would have
helped me orient more quickly without having to go and dig around
in the code overly much.

* Add support for free-busy endpoint (#279)

* Add support for free-busy endpoint

Mostly cribbed off the availability support, though radically stripped
down as free-busy is a great deal simpler.

* debugging

* just work

* fix docs

* fix doc

* rename Error to FreeBusyError

* Change auth build query to point to scope instead of scopes (#283)

Co-authored-by: Kiran Raju <[email protected]@Kirans-MacBook-Pro-2.local>

* Fix KeyError when building Auth URL (#284)

We were not properly checking the existence of an entry in a dict.

* Add Connector support (#292)

This PR adds support for the connector endpoints.

* Nylas Credentials API v3 (#293)

New PR for Credentials API support. Introduced a new class for UpdateRequest and fixed other issues with typing

* v6.0.0 Beta 4 Release (#294)

* Update CHANGELOG.md

* Bump version: 6.0.0b3 β†’ 6.0.0b4

* Changes to calendars and grants models and resources to not fail on decoding. (#300)

Co-authored-by: [email protected] <[email protected]>

* Fix creating a grant/custom auth (#299)

This PR fixes creating a grant by pointing it to the custom auth endpoint.

* v6.0.0 beta 5 release (#302)

* Update CHANGELOG.md

* Bump version: 6.0.0b4 β†’ 6.0.0b5

* document how to enable requests DEBUG logs (#304)

* remove unused imports (#303)

* Add support for Read, Update, and Delete for Messages (#305)

RUD support for Messages API

* Making timezone value and timestamps for Grant optional due to no support in our API's (#306)

* Document events.find() too for comprehensive quickstart (#307)

* v6.0.0 beta 6 Release (#308)

* Update CHANGELOG.md

* Bump version: 6.0.0b5 β†’ 6.0.0b6

* Make "To" Optional (#309)

When sending an email without a To (using bc or bcc), fetching breaks.

* Add Message Send, Drafts, Threads, and Smart Compose APIs support (#310)

This PR builds on #305. Adds the remaining message-related endpoints and models. This PR also brings forward a few breaking changes that alter behaviour to #305:
- In `ListMessageQueryParams` anything that was a list type in the API (to, bcc, etc.) are now List type as well. We then convert these arrays to comma delimited strings fit for the API.
- `Attachments` have moved to `models/attachments.py` as we needed a common space for both `Message` and `Draft` objects to pull from.

* Folders API support (#311)

This PR adds support for the folders API.

* Attachments API Support (#312)

This PR adds support for the Attachments API.

* v6.0.0 beta 7 Release (#314)

Changelog:
* Add Message Send, Drafts, Threads, and Smart Compose APIs support (#310)
* Add support for folders API (#311)
* Add support for attachments API (#312)
* Fix required field for the `Message` model (#309)

* Fix message send/draft create/modify not working properly (#315)

This PR fixes the serialization of outgoing message requests using the multipart formatter. We've also added in a helper function to help with formatting files to attach to a message.

* Fix required fields in Thread (#322)

Fix some optional fields to be able to return a thread

* Move `Grants` to `NylasClient` and custom authentication to `Auth` (#324)

* Move custom auth out of grants to auth

* move grants entry point out of auth to nylasclient

* Update CHANGELOG.md

* Fix issue with multipart attachments throwing KeyError (#319)

* fix attaching files via multipart

* Update CHANGELOG.md

* Fix inaccuracies with Event models (#317)

* Fix inaccuracies with Event models

* fix calendar typo

* timestamps should be int

* Add contact objects

* Add Contact CRUD support

* Add contact group support

* Fixes for contacts api

Found some bugs on AV-1465-3-0-ga-python-sdk-contacts-api so this PR should address them as I have fully tested them.

* Contacts API support (#325)

This PR adds support for the Contacts API.

* Fix incorrect PKCE code challenge generation (#330)

This PR fixes the PKCE code challenge generation; the correct method the API wants is for us to base64 encode the hex string as opposed to base64 encoding resulting hashed bytearray directly. Closes #329. Thanks to @wobeng for reporting and providing the correct code.

Co-authored-by: Welby O. <[email protected]>

* v6.0.0 beta 8 Release (#331)

* linting

* Bump version: 6.0.0b7 β†’ 6.0.0b8

* Update CHANGELOG.md

* Update client.py to add Drafts (#333)

Added the call to Drafts endpoint

* Fix drafts API entrypoint (#334)

* Add support for sending drafts (#336)

This PR adds support for sending drafts.

* Update events.py to add capacity (#335)

Add capacity to the events response

* Changed client_secret to optional for token exchange methods; defaults to API Key now (#337)

client_secret is not required if the API Key used for the SDK and the clientId belong to the same application.

* Python testing framework + fixes (#323)

This PR adds the full testing suite for Python. This also includes the following fixes:
* Changed references to `callback_url` to `webhook_url` to match API
* Fix deserialization issue with `Connector` model
* Fix serialization of query parameters
* Fix typos in folders, threads, code exchange, smart compose, webhook and attachment models
* Fix types in reminder and messages models
* Fix message/draft deserialization in thread model
* Standardized casing for enums

* Fix fields for creating drafts and sending messages (#338)

Fix fields for creating drafts and sending messages.

* Add pylint step and address linting issues (#339)

This PR runs pytest for the first time and fixes all offences (after disabling certain rules), and adds a step to lint to the CI steps.

* v6.0.0 beta 9 Release (#340)

# Changelog
* Add support for sending drafts
* Changed `client_secret` to optional for token exchange methods; defaults to API Key now
* Changed references to `callback_url` to `webhook_url` to match API
* Fix deserialization issue with `Connector` model
* Fix serialization of query parameters
* Fix typos in folders, threads, code exchange, smart compose, webhook and attachment models
* Fix types in reminder and messages models
* Fix message/draft deserialization in thread model
* Standardized casing for enums

* Update CHANGELOG.md

* scrub references to the beta

* Bump version: 6.0.0b9 β†’ 6.0.0

---------

Co-authored-by: Christine Spang <[email protected]>
Co-authored-by: Christine Spang <[email protected]>
Co-authored-by: kraju3 <[email protected]>
Co-authored-by: Kiran Raju <[email protected]@Kirans-MacBook-Pro-2.local>
Co-authored-by: [email protected] <[email protected]>
Co-authored-by: Blag <[email protected]>
Co-authored-by: Welby O. <[email protected]>
  • Loading branch information
8 people authored Feb 5, 2024
1 parent 247a70f commit d71acbe
Show file tree
Hide file tree
Showing 151 changed files with 9,486 additions and 11,422 deletions.
3 changes: 0 additions & 3 deletions .arcconfig

This file was deleted.

2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[bumpversion]
commit = True
tag = True
current_version = 5.14.1
current_version = 6.0.0

[bumpversion:file:nylas/_client_sdk_version.py]
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
[run]
source = nylas
omit = tests/*
43 changes: 43 additions & 0 deletions .github/workflows/sdk-reference.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: sdk-reference

on:
push:
branches:
- main
pull_request:

jobs:
docs:
runs-on: ubuntu-latest
environment:
name: sdk-reference
url: ${{ steps.deploy.outputs.url }}
steps:
- uses: actions/checkout@v2
- name: Setup Nodejs
uses: actions/setup-python@v2
with:
python-version: 3.8
- name: Install dependencies and build
run: pip install .[docs]
- name: Build docs
run: python setup.py build-docs
- name: Set env BRANCH
run: echo "BRANCH=$(echo $GITHUB_REF | cut -d'/' -f 3)" >> $GITHUB_ENV
- name: Set env CLOUDFLARE_BRANCH
run: |
if [[ $BRANCH == 'main' && $GITHUB_EVENT_NAME == 'push' ]]; then
echo "CLOUDFLARE_BRANCH=main" >> "$GITHUB_ENV"
else
echo "CLOUDFLARE_BRANCH=$BRANCH" >> "$GITHUB_ENV"
fi
- name: Publish to Cloudflare Pages
uses: cloudflare/pages-action@v1
id: deploy
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: nylas-python-sdk-reference
directory: site
wranglerVersion: "3"
branch: ${{ env.CLOUDFLARE_BRANCH }}
20 changes: 13 additions & 7 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ["2.x", "3.x"]
python-version: ["3.8", "3.x"]
name: Python ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v2
- name: Setup python
uses: MatteoH2O1999/setup-python@v1.4.1
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python-version }}

Expand All @@ -35,16 +35,22 @@ jobs:

black:
runs-on: ubuntu-latest
name: Black
name: Pylint and Black
steps:
- uses: actions/checkout@v2
- name: Setup python
uses: actions/setup-python@v2
with:
python-version: "3.x"
python-version: "3.8"

- name: Install dependencies
run: pip install .

- name: Install pylint and black
run: pip install pylint black

- name: Install black
run: pip install black
- name: Run pylint
run: pylint nylas

- name: Run black
run: black --check --extend-exclude="/examples" .
run: black .
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,9 @@ local/
pip-selfcheck.json
tests/output
local.env
examples/test.py
test.py
.env

# Documentation
site
docs
31 changes: 31 additions & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[FORMAT]
good-names=id,k,v,cc,to,ip
max-line-length=120

[MESSAGES CONTROL]
disable=
missing-module-docstring,
arguments-differ,
protected-access,
duplicate-code,
too-many-instance-attributes,
unnecessary-pass,
too-many-arguments,
too-few-public-methods,

[TYPECHECK]

generated-members=
Message.from_dict,
Draft.from_dict,
Time.from_dict,
Timespan.from_dict,
Date.from_dict,
Datespan.from_dict,
Details.from_dict,
Autocreate.from_dict,
RequestIdOnlyResponse.from_dict,
TokenInfoResponse.from_dict,
CodeExchangeResponse.from_dict,
NylasApiErrorResponse.from_dict,
NylasOAuthErrorResponse.from_dict,
20 changes: 19 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
nylas-python Changelog
======================

Unreleased
v6.0.0
----------------
* **BREAKING CHANGE**: Python SDK v6 supports the Nylas API v3 exclusively, dropping support for any endpoints that are not available in v3
* **BREAKING CHANGE**: Drop support for Python < v3.8
* **BREAKING CHANGE**: Dropped the use of 'Collections' in favor of 'Resources'
* **BREAKING CHANGE**: Removed all REST calls from models and moved them directly into resources
* **BREAKING CHANGE**: Models no longer inherit from `dict` but instead either are a `dataclass` or inherit from `TypedDict`
* **BREAKING CHANGE**: Renamed the SDK entrypoint from `APIClient` to `Client`
* **REMOVED**: Local Webhook development support is removed due to incompatibility
* Rewrote the majority of SDK to be more intuitive, explicit, and efficient
* Created models for all API resources and endpoints, for all HTTP methods to reduce confusion on which fields are available for each endpoint
* Created error classes for the different API errors as well as SDK-specific errors

v5.14.1
----------------
* Fix error when trying to iterate on list after calling count
* Fix error when setting participant status on create event

v5.14.0
----------------
* Add support for `view` parameter in `Threads.search()`

Expand Down
100 changes: 74 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,34 @@

# Nylas Python SDK

[![GitHub Workflow Status](https://img.shields.io/github/workflow/status/nylas/nylas-python/Test)](https://github.com/nylas/nylas-python/actions/workflows/test.yml)
[![PyPI - Version](https://img.shields.io/pypi/v/nylas)](https://pypi.org/project/nylas/)
[![codecov](https://codecov.io/gh/nylas/nylas-python/branch/main/graph/badge.svg?token=HyxGAn5bJR)](https://codecov.io/gh/nylas/nylas-python)

This is the GitHub repository for the Nylas Python SDK and this repo is primarily for anyone who wants to make contributions to the SDK or install it from source. If you are looking to use Python to access the Nylas Email, Calendar, or Contacts API you should refer to our official [Python SDK Quickstart Guide](https://docs.nylas.com/docs/quickstart-python).
This is the GitHub repository for the Nylas Python SDK. The repo is primarily for anyone who wants to install the SDK from source or make contributions to it.

The Nylas Communications Platform provides REST APIs for [Email](https://docs.nylas.com/docs/quickstart-email), [Calendar](https://docs.nylas.com/docs/quickstart-calendar), and [Contacts](https://docs.nylas.com/docs/quickstart-contacts), and the Python SDK is the quickest way to build your integration using Python
If you're looking to use Python to access the Nylas Email, Calendar, or Contacts APIs, see our [Python SDK Quickstart guide](https://docs.nylas.com/docs/quickstart-python).

The Nylas platform provides REST APIs for [Email](https://docs.nylas.com/docs/quickstart-email), [Calendar](https://docs.nylas.com/docs/quickstart-calendar), and [Contacts](https://docs.nylas.com/docs/quickstart-contacts), and the Python SDK is the quickest way to build your integration using Python.

Here are some resources to help you get started:

- [Nylas SDK Tutorials](https://docs.nylas.com/docs/tutorials)
- [Get Started with the Nylas Communications Platform](https://docs.nylas.com/docs/getting-started)
- [Sign up for your Nylas developer account.](https://nylas.com/register)
- [Nylas API Reference](https://docs.nylas.com/reference)
- [Sign up for a free Nylas account](https://dashboard.nylas.com/register).
- Follow the [Nylas API v3 Quickstart guide](https://developer.nylas.com/docs/v3-beta/v3-quickstart/).
- Browse the [Nylas SDK reference docs](https://nylas-python-sdk-reference.pages.dev/).
- Browse the [Nylas API reference docs](https://developer.nylas.com/docs/api/).
- See our code samples in the [Nylas Samples repo](https://github.com/orgs/nylas-samples/repositories?q=&type=all&language=python).

If you have a question about the Nylas Communications Platform, please reach out to [email protected] to get help.
If you have any questions about the Nylas platform, please reach out to [email protected].

## βš™οΈ Install

The Nylas Python SDK is available via pip:

```bash
pip install nylas
pip install nylas --pre
```

To install the SDK from source, clone this repo and run the install script.
To install the SDK from source, clone this repo and run the install script:

```bash
git clone https://github.com/nylas/nylas-python.git && cd nylas-python
Expand All @@ -37,38 +40,83 @@ python setup.py install

## ⚑️ Usage

To use this SDK, you first need to [sign up for a free Nylas developer account](https://nylas.com/register).
Before you use the Nylas Python SDK, you must first [create a Nylas account](https://dashboard.nylas.com/register). Then, follow our [API v3 Quickstart guide](https://developer.nylas.com/docs/v3-beta/v3-quickstart/) to set up your first app and get your API keys.

For code samples and example applications, take a look at our [Python repos in the Nylas Samples collection](https://github.com/orgs/nylas-samples/repositories?q=&type=all&language=python).

Then, follow our guide to [setup your first app and get your API access keys](https://docs.nylas.com/docs/get-your-developer-api-keys).
### πŸš€ Make your first request

Next, in your python script, import the `APIClient` class from the `nylas` package, and create a new instance of this class, passing the variables you gathered when you got your developer API keys. In the following example, replace `CLIENT_ID`, `CLIENT_SECRET`, and `ACCESS_TOKEN` with your values.
After you've installed and set up the Nylas Python SDK, you can make your first API request. To do so, use the `Client` class from the `nylas` package.

The SDK is organized into different resources, each of which has methods to make requests to the Nylas API. Each resource is available through the `Client` object that you configured with your API key. For example, you can use this code to get a list of Calendars:

```python
from nylas import APIClient
from nylas import Client

nylas = APIClient(
CLIENT_ID,
CLIENT_SECRET,
ACCESS_TOKEN
nylas = Client(
api_key="API_KEY",
)
```

Now, you can use `nylas` to access full email, calendar, and contacts functionality. For example, here is how you would print the subject line for the most recent email message to the console.
calendars, request_id, next_cursor = nylas.calendars.list("GRANT_ID")

event, request_id = nylas.events.create(
identifier="GRANT_ID",
request_body={
"title": "test title",
"description": "test description",
"when": {
"start_time": start_unix_timestamp,
"end_time": end_unix_timestamp,
}
},
query_params={"calendar_id": "primary", "notify_participants": True},
)
)

event, request_id = nylas.events.find(
identifier="GRANT_ID",
event_id=event.id,
query_params={
"calendar_id": "primary",
},
)

nylas.events.destroy("GRANT_ID", event.id, {"calendar_id": "primary"})

```python
message = nylas.messages.first()
print(message.subject)
```

To learn more about how to use the Nylas Python SDK, please refer to our [Python SDK QuickStart Guide](https://docs.nylas.com/docs/quickstart-python) and our [Python tutorials](https://docs.nylas.com/docs/tutorials).
## πŸ“š Documentation

This SDK makes heavy use of [Python 3 dataclasses](https://realpython.com/python-data-classes/) to define the REST resources and request/response schemas of the Nylas APIs. The Client object is a wrapper around all of these resources and is used to interact with the corresponding APIs. Basic CRUD operations are handled by the `create()`, `find()`, `list()`, `update()`, and `destroy()` methods on each resource. Resources may also have other methods which are all detailed in the [reference guide for the Python SDK](https://nylas-python-sdk-reference.pages.dev/). In the code reference, start at `client`, and then `resources` will give more info on available API call methods. `models` is the place to find schemas for requests, responses, and all Nylas object types.

While most resources are accessed via the top-level Client object, note that `auth` contains the sub-resource `grants` as well as a collection of other auth-related API calls.

## πŸ’™ Contributing
You'll want to catch `nylas.models.errors.NylasAPIError` to handle errors.

Have fun!!

## ✨ Upgrade from v5.x

See [UPGRADE.md](UPGRADE.md) for instructions on upgrading from v5.x to v6.x.

## πŸ’™ Contribute

Please refer to [Contributing](Contributing.md) for information about how to make contributions to this project. We welcome questions, bug reports, and pull requests.

Taking part in Hacktoberfest 2023 (i.e. issue is tagged with `hacktoberfest`)? Read our [Nylas Hacktoberfest 2023 contribution guidelines](https://github.com/nylas-samples/nylas-hacktoberfest-2023/blob/main/readme.md).
## πŸ› οΈ Debugging

It can sometimes be helpful to turn on request logging during development. Adding the following snippet to your code that calls the SDK should get you sorted:

```
import logging
import requests
# Set up logging to print out HTTP request information
logging.basicConfig(level=logging.DEBUG)
requests_log = logging.getLogger("requests.packages.urllib3")
requests_log.setLevel(logging.DEBUG)
requests_log.propagate = True
```

## πŸ“ License

Expand Down
Loading

0 comments on commit d71acbe

Please sign in to comment.