SCIM API
The Anaplan SDK provides access to the SCIM (System for Cross-domain Identity Management) API for managing user identities within your Anaplan tenant. Despite its name, the Anaplan SCIM API is only partially RFC 7643 & RFC 7644 compliant.
Basic Usage
from anaplan_sdk import Client
anaplan = Client(
certificate=getenv("ANAPLAN_CERT"), private_key=getenv("ANAPLAN_PK")
)
# See Available Features
config = anaplan.scim.get_service_provider_config()
resources = anaplan.scim.get_resource_types() # See Available Resources
schemas = anaplan.scim.get_resource_schemas() # See Available Schemas
users = anaplan.scim.get_users() # All internal users
user = anaplan.scim.get_user("123") # specific user
from asyncio import gather
from anaplan_sdk import AsyncClient
anaplan = AsyncClient(
certificate=getenv("ANAPLAN_CERT"), private_key=getenv("ANAPLAN_PK")
)
config, resources, schemas, users, user = await gather(
anaplan.scim.get_service_provider_config(), # See Available Features
anaplan.scim.get_resource_types(), # See Available Resources
anaplan.scim.get_resource_schemas(), # See Available Schemas
anaplan.scim.get_users(), # All internal users
anaplan.scim.get_user("123"), # specific user
)
Filtering Users
You can filter users based on specific attributes by passing a predicate string as per the RFC, e.g. active eq true
.
users = await anaplan.scim.get_users("active eq true")
users = await anaplan.scim.get_users("active eq true")
Anaplan supports filtering by the following attributes:
id
, externalId
, userName
, name.givenName
, name.familyName
, active
and the following operators:
eq
, ne
, gt
, ge
, lt
, le
and pr
. These can be combined with and
and or
logical operators and grouped with parentheses (
and )
.
As an alternative to manually constructing the filter predicate string, you can use the expression language provided by the SDK to build the filter expression programmatically. This approach can help avoid syntax errors and improve readability, and make is easier to compose more complex expressions. The expression language is heavily inspired by the polars expression syntax.
The expression langauge supports all operators implemented by Anaplan, is fully type-hinted, reducing the risk of referencing fields you cannot filter by. It also supports truthy / falsy values allowing you to avoid explicitly spelling out == True
comparisons.
from anaplan_sdk import field
part = (
field("active") # "active eq true"
& field("userName") # "userName pr"
& (field("name.givenName") > "Thomas")
)
predicate = (field("userName") == "test.user@valantic.com") | (
part | (~field("active") & (field("name.givenName") != "Thomas"))
)
Note that we need to wrap (~field("active")
in parentheses to ensure the correct operator precedence. Anaplan does not support the not
operator,
~field("active") & (field("name.givenName") != "Thomas")
would thus be invalid, since we cannot negate the logical expression and the &
evaluates before the ~
.
Updating Users
You can update users by performing partial operations on specific attributes or by replacing the entire user object. You can pass the provided Pydantic models, or a dictionary with the appropriate structure. If you pass a dictionary, it will be validated against the Pydantic models before being sent to Anaplan. This avoids unnecessary requests and gives you more concise error messages.
from anaplan_sdk.models.scim import Remove, Replace
user = anaplan.scim.update_user(
"123",
[Replace(path="active", value=False), Remove(path="entitlements")],
)
from anaplan_sdk.models.scim import Remove, Replace
user = await anaplan.scim.update_user(
"123",
[Replace(path="active", value=False), Remove(path="entitlements")],
)
Both methods return an updated user object.
from anaplan_sdk.models.scim import NameInput, ReplaceUserInput
user = anaplan.scim.replace_user(
"123",
ReplaceUserInput(
id="123",
name=NameInput(given_name="Test", family_name="User"),
user_name="test.user@valantic.com",
),
)
from anaplan_sdk.models.scim import NameInput, ReplaceUserInput
user = await anaplan.scim.replace_user(
"123",
ReplaceUserInput(
id="123",
name=NameInput(given_name="Test", family_name="User"),
user_name="test.user@valantic.com",
),
)