scim2-models

Pydantic v2 models for SCIM2 resources and messages, implementing RFC7643 and RFC7644 with context-aware validation and serialization.

Library
PyPI
v0.6.12
29stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
60/100Good
Development Activity72
Maintenance80
Community20
Maturity48
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
86/100Excellent
Architecture88
Code Quality92
Innovation78
Learning Curve85

scim2-models gives Python developers native, type-checked classes for the resources and protocol messages defined by the SCIM2 specification (RFC7643 for schema, RFC7644 for protocol). Instead of hand-rolling dict-based payload handling for User, Group, EnterpriseUser, ServiceProviderConfig, ResourceType, and Schema objects, consumers get full Pydantic v2 models with IDE autocompletion, validation, and serialization built in.

What sets it apart from generic schema libraries is its context-aware validation system: the same model can be serialized or validated differently depending on whether it is being used for a resource creation request, a query response, a replacement, a patch, or a search — mirroring the mutability (readOnly, writeOnly, readWrite, immutable) and returned (always, never, default, request) semantics baked into the SCIM spec itself. It also ships SCIM protocol messages (ListResponse, SearchRequest, PatchOp, Error), SCIM-compliant exception types that convert automatically into spec-shaped error responses, and support for dynamic schema extensions so custom resource types and attributes can be modeled and converted at runtime.

It is maintained by Yaal Coop as the foundational model layer for a small family of SCIM tools (scim2-client, scim2-tester, scim2-cli), making it the natural starting point for anyone building a SCIM2 client or server in Python.

What You Get

  • Native Pydantic classes for core SCIM resources: User, Group, EnterpriseUser, ServiceProviderConfig, ResourceType, and Schema
  • Context-aware validation and serialization that automatically applies the correct mutability/returned rules for creation, query, replacement, patch, and search HTTP contexts
  • SCIM protocol message types: ListResponse, SearchRequest, PatchOp/PatchOperation, BulkRequest/BulkResponse, and Error
  • Field-level metadata annotations (Mutability, Returned, Uniqueness, Required, CaseExact) that mirror RFC7643 attribute characteristics
  • Dynamic schema extension support, including runtime conversion between schema definitions and Python model classes
  • SCIM-compliant exception hierarchy (InvalidFilterException, MutabilityException, UniquenessException, etc.) that converts directly into spec-shaped Error responses

Common Use Cases

  • Building a SCIM2 server - validate inbound provisioning requests from an Identity Provider and shape outbound responses to match the exact fields the spec allows for each context
  • Building a SCIM2 client - construct and serialize creation, query, and patch requests against a third-party SCIM-compliant API with confidence the payload is spec-correct
  • Implementing enterprise user provisioning - model EnterpriseUser extensions (department, manager, cost center) alongside core User attributes without custom parsing code
  • Handling PATCH operations - parse and apply PatchOp/PatchOperation payloads for add/remove/replace semantics defined in RFC7644 §3.5.2
  • Supporting custom resource schemas - use dynamic schema extension to model organization-specific SCIM resource types beyond the core spec

Under The Hood

Architecture The package is organized around a BaseModel (scim2_models/base.py) that extends Pydantic’s BaseModel with SCIM-specific behavior: custom model_serializer/model_validator hooks read Context enum values to decide which fields to include or reject, based on per-field Mutability and Returned annotations attached via typing.Annotated. Resource and message classes (scim2_models/resources/, scim2_models/messages/) subclass this base and declare their fields with those annotations rather than encoding context logic per-model. A separate path.py module implements SCIM path expression parsing (used for PATCH operations and attribute selection) as its own resolver over the model tree, and lookup.py provides schema-URN-to-class resolution so payloads can be deserialized into the correct dynamic or extension type at runtime. This clean separation — annotation-driven validation, a dedicated path resolver, and a schema lookup registry — means adding a new resource type is mostly a matter of declaring fields with the right annotations rather than writing new validation logic.

Tech Stack The library targets Python 3.10+ and has a single runtime dependency: pydantic[email]>=2.12.0. It uses uv_build as its build backend and uv.lock for dependency locking, ruff for linting/formatting (with pydocstyle, pyupgrade, and isort rule sets enabled), and mypy in strict mode with the pydantic.mypy plugin for full static type checking. Documentation is built with Sphinx plus autodoc-pydantic and the Shibuya theme, and testing/tooling orchestration runs through tox with uv-based environments covering multiple Python versions (3.10-3.14) plus a dedicated minimum-versions check.

Code Quality The project has an extensive test suite (25+ test files covering path parsing, dynamic schemas/resources, patch operations, exceptions, validation, and serialization individually) run via pytest with --doctest-modules so every module and reStructuredText doctest is also exercised as a test. Coverage is configured to fail under 100% in the dedicated coverage tox environment, and mypy --strict is enforced project-wide (excluding tests). Docstrings follow a consistent RFC-referencing style throughout the codebase, and pre-commit hooks (prek) plus a GitHub Actions test workflow gate changes before merge.

What Makes It Unique Most general-purpose Python validation libraries (Pydantic itself, Marshmallow, attrs) have no built-in concept of “this field behaves differently depending on which HTTP operation is happening” — that’s a SCIM-specific requirement. scim2-models bakes RFC7643’s mutability/returned semantics directly into its Context enum and field annotation system, so the same model definition correctly enforces different validation and serialization rules for resource creation, query, replacement, patch, and search without consumers writing per-endpoint logic themselves. Combined with dynamic schema extension support for custom resource types, it functions less like a generic data-modeling library and more like a purpose-built protocol implementation layer for SCIM2.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search