The v5 release is a major rewrite to add typing and improve consistency across the SDK. There are several breaking changes, which we recommend carefully testing before upgrading the SDK in production.
What’s New
- Type hints added across the entire SDK to make it safer and easier to integrate WorkOS
- `asyncio` support added to several feature modules including Directory Sync, Events, Organizations, SSO, and User Management
- All API methods return typed models
- Simplified auto pagination - see details in “breaking changes” section below.
- Support for multiple clients with different credentials
Breaking Changes & Migration Guide
General
- To support WorkOS client instantiations with different API keys, client instantiation has been modified:
python
Previous client setup
import workos
workos.api_key = "sk_1234"
workos.client_id="client_1234"
New client instantiation
from workos import WorkOSClient
workos_client = WorkOSClient(
api_key="sk_1234", client_id="client_1234"
)
- Client ID is now required during instantiation. Your client ID can be found on the [API keys page of the WorkOS dashboard](https://dashboard.workos.com/api-keys).
- To increase readability of passing arguments to our API methods, all API methods with more than one argument are now required to be passed as keyword arguments:
python
Previous usage
workos.client.directory_sync.list_users(
"directory_123", "group_456", 10
)
New usage
workos_client.directory_sync.list_users(
directory_id="directory_123",
group_id="group_456",
limit=10
)
- **For all API methods**, return values are now objects instead of dictionaries. This means properties are now accessed via dot notation instead of dictionary key indexes. These models can be converted to their dictionary equivalent by calling the `.dict()` method. See the example below:
python
Previous implementation
user = workos.client.user_management.get_user(user_id="user_123")
email = user["email"]
New implementation
user = workos_client.user_management.get_user(user_id="user_123")
email = user.email
Alternatively, the user object can be converted to a dictionary
user = workos_client.user_management.get_user(user_id="user_123")
user_dictionary = user.dict()
email = user["email"]
- Auto pagination now automatically returns the resource entities only and is used implicitly by iterating using a list method, instead of explicitly calling .auto_paging_iter(). For example, to iterate over all SSO connections, you’d do the following:
python
all_connections = []
for connection in workos_client.sso.list_connections():
all_connections.append(connection)
- All unique ID parameters have to be suffixed with `_id` for clarity, this introduced a number of breaking changes listed in the feature sections below
- `Order` for list methods has been removed in favor of the `PaginationOrder` string literal. Instead of specifying `Order.desc` or `Order.asc`, use the literal strings `desc` and `asc`, respectively.
API-specific Breaking Changes
Audit Log APIs
- **audit_logs.create_event()**
- `organization` argument renamed to `organization_id`
- If using typing, event is now required to be an `AuditLogEvent` `TypedDict` from `workos.types.audit_logs`
- **audit_logs.create_export()**
- `actors` argument has been removed. Use `actor_names` and `actor_ids` instead.
- `organization` argument renamed to `organization_id`
Directory Sync APIs
- **directory_sync.delete_directory()** → `directory` argument renamed to `directory_id`
- **directory_sync.get_directory()** → `directory` argument renamed to `directory_id`
- **directory_sync.get_group()** → `group` argument renamed to `group_id`
- **directory_sync.get_user()** → `user` argument renamed to `user_id`
- **directory_sync.list_groups()**
- The deprecated version of `directory_sync.list_groups()` has been removed. `directory_sync.list_groups_v2()` has been renamed to `directory_sync.list_groups()`.
- `directory` argument renamed to `directory_id`
- `user` argument renamed to `user_id`
- **directory_sync.list_users()**
- The deprecated version of `directory_sync.list_users()` has been removed. `directory_sync.list_users_v2()` has been renamed to `directory_sync.list_users()`.
- `directory` argument renamed to `directory_id`
- `group` argument renamed to `group_id`
MFA APIs
- `mfa.verify_factor()` has been removed. Use `mfa.verify_challenge()` instead.
Organizations APIs
- The deprecated version of `organizations.list_organizations()` has been removed. `organizations.list_organizations_v2()` is now `organizations.list_organizations()`.
- `organizations.create_organization()` now takes payload contents as separate arguments:
python
Previous implementation
organization = workos_client.organizations.create_organization(
{
"name": "Foo Corp",
"domain_data": [
{
"domain": "foo-corp.com",
"state": "pending",
}
],
}
)
New implementation
create_organization_payload = {
"name": "Foo Corp",
"domain_data": [
{
"domain": "foo-corp.com",
"state": "pending",
}
],
}
organization = workos_client.organizations.create_organization(
**create_organization_payload
)
- **organizations.delete_organization()** → `organization` argument renamed to `organization_id`
- **organizations.get_organization()** → `organization` argument renamed to `organization_id`
- **organizations.update_organization()** → `organization` argument renamed to `organization_id`
Passwordless APIs
- `passwordless.create_session()` now takes payload contents as separate arguments:
python
Previous implementation
passwordless_session = workos_client.passwordless.create_session({
"email": "marcelinaexample.com",
"type": "MagicLink",
})
New implementation
passwordless_session = workos_client.passwordless.create_session(
email="marcelinaexample.com",
type="MagicLink",
)
- **passwordless.send_session()** → `id` argument renamed to `session_id`
Portal APIs
- **portal.generate_link()** → `organization` argument renamed to `organization_id`
SSO APIs
- **sso.list_connections()**
- The deprecated version of `sso.list_connections()` has been removed. `sso.list_connections_v2()` has been renamed to `sso.list_connections()`.
- `organization` argument renamed to `organization_id`
- **sso.delete_connection()** → `connection` argument renamed to `connection_id`
- **sso.get_authorization_url()**
- `domains` argument has been removed. Use the `organization` argument instead.
- `connection` argument renamed to `connection_id`
- `organization` argument renamed to `organization_id`
- **sso.get_connection()** → `connection` argument renamed to `connection_id`
- **sso.get_profile()** → `accessToken` argument renamed to `access_token`
User Management APIs
- **user_management.get_authorization_url()** → `provider` argument of type `UserManagementProviderType` is now a string literal instead of an enum
- **user_management.get_logout_url()** → `session` argument renamed to `session_id`
- **user_management.create_user()** now takes payload contents as separate arguments:
python
Previous implementation
user = workos_client.user_management.create_user(
{
"email": "marcelinaexample.com",
"password": "i8uv6g34kd490s",
"first_name": "Marcelina",
"last_name": "Davis",
}
)
New implementation
create_user_payload = {
"email": "marcelinaexample.com",
"password": "i8uv6g34kd490s",
"first_name": "Marcelina",
"last_name": "Davis",
}
user = workos_client.user_management.create_user(**create_user_payload)
- `user_management.update_user()` now takes payload contents as separate arguments:
python
Previous implementation
user = workos_client.user_management.update_user(
user_id="user_01EHQ7ZGZ2CZVQJGZ5ZJZ1ZJGZ",
payload={"first_name": "Marcelina", "last_name": "Davis", "email_verified": True},
)
New implementation
update_user_payload = {
"first_name": "Marcelina",
"last_name": "Davis",
"email_verified": True,
}
user = workos_client.user_management.update_user(
user_id="user_01EHQ7ZGZ2CZVQJGZ5ZJZ1ZJGZ",
**update_user_payload,
)
- `user_management.send_password_reset_email()` has been removed. Use `user_management.create_password_reset()` instead.
- `user_management.send_magic_auth_code()` has been removed. Use `user_management.create_magic_auth()` instead.