The missing types for Pydantic — cloud, DevOps, web, and data engineering.
Project description
pydantypes
The missing types for Pydantic — cloud, DevOps, web, data, and AI engineering.
pydantypes provides validated, constrained Pydantic types for identifiers, ARNs, URIs, resource names, and classification labels that appear everywhere in modern infrastructure and AI code. Catch invalid values at parse time, not at deploy time.
Installation
pip install pydantypes
# or
uv add pydantypes
Quick Example
Every type validates and parses — you get structured properties, not just accept/reject.
from pydantic import BaseModel
from pydantypes.cloud.aws import S3Uri, IamRoleArn
class PipelineConfig(BaseModel):
source: S3Uri
execution_role: IamRoleArn
config = PipelineConfig(
source="s3://my-bucket/data/input.parquet",
execution_role="arn:aws:iam::123456789012:role/pipeline-role",
)
config.source.bucket # "my-bucket"
config.source.key # "data/input.parquet"
config.execution_role.role_name # "pipeline-role"
Domains
| Domain | Package | What You Get |
|---|---|---|
| AWS | pydantypes.cloud.aws |
S3 URIs, IAM ARNs, Lambda names, EC2/ECS/EKS IDs, account IDs, regions |
| Azure | pydantypes.cloud.azure |
Blob Storage URIs, resource IDs, Key Vault names, subscription IDs |
| GCP | pydantypes.cloud.gcp |
GCS URIs, project IDs, service account emails, Cloud Run services |
| DevOps | pydantypes.devops |
Docker image refs, Git SHAs/refs/URLs, K8s names/labels, Helm charts, Terraform addresses |
| Web | pydantypes.web |
Hosts, URNs, slugs, JWTs, MIME types, FQDNs, port ranges, Bearer tokens, hashes |
| Data | pydantypes.data |
SQL identifiers, Kafka topics, connection strings, column names |
| AI | pydantypes.ai |
Classification labels with lifecycle, deprecation, alias resolution |
Types You Won't Find Anywhere Else
Parse cloud resources into structured components
from pydantypes.cloud.aws import Arn
from pydantypes.cloud.azure import ResourceId
arn = Arn("arn:aws:iam::123456789012:role/pipeline-role")
arn.service # "iam"
arn.account_id # "123456789012"
arn.resource # "role/pipeline-role"
rid = ResourceId(
"/subscriptions/12345678-1234-1234-1234-123456789012"
"/resourceGroups/myRG/providers/Microsoft.Compute/virtualMachines/myVM"
)
rid.subscription_id # "12345678-1234-1234-1234-123456789012"
rid.resource_group # "myRG"
rid.provider_namespace # "Microsoft.Compute"
rid.resource_type # "virtualMachines"
rid.resource_name # "myVM"
Decompose Docker refs and Git URLs
from pydantypes.devops import DockerImageRef, GitSshUrl
img = DockerImageRef("ghcr.io/owner/app:v2.1@sha256:abcdef1234567890")
img.registry # "ghcr.io"
img.repository # "owner/app"
img.tag # "v2.1"
img.digest # "sha256:abcdef1234567890"
url = GitSshUrl("git@github.com:torvalds/linux.git")
url.host # "github.com"
url.owner # "torvalds"
url.repo # "linux"
Validate web identifiers with RFC-compliant parsing
from pydantypes.web import Host, Urn, Jwt, MimeType
host = Host("[2001:db8::1]")
host.host_type # "ipv6"
host = Host("api.example.com")
host.host_type # "domain"
urn = Urn("urn:isbn:0451450523")
urn.nid # "isbn"
urn.nss # "0451450523"
jwt = Jwt("eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NSJ9.signature")
jwt.header # {"alg": "HS256"}
jwt.payload # {"sub": "12345"}
mime = MimeType("application/json;charset=utf-8")
mime.type # "application"
mime.subtype # "json"
mime.parameters # {"charset": "utf-8"}
Manage classification label lifecycles
Nothing like this exists in the Pydantic ecosystem. LabelEnum gives you typed classification labels for LLM and ML projects — with descriptions, deprecation warnings, retirement enforcement, and alias resolution built in. Compatible with OpenAI structured outputs, LangChain with_structured_output, and all Pydantic-based LLM frameworks.
from pydantic import BaseModel
from pydantypes.ai import LabelEnum, Label
class Sentiment(LabelEnum):
POSITIVE = Label("positive", description="Expresses approval or satisfaction")
NEGATIVE = Label("negative", description="Expresses disapproval or frustration")
NEUTRAL = Label("neutral", description="No clear emotional signal")
# Taxonomy evolves — deprecate old labels without breaking existing data
MIXED = Label(
"mixed",
deprecated=True,
successor="NEUTRAL",
description="Contradictory signals",
)
# Retired labels are rejected outright, but aliases still resolve
AMBIGUOUS = Label(
"ambiguous",
retired=True,
successor="NEUTRAL",
aliases=["unclear", "unknown"],
)
class Result(BaseModel):
sentiment: Sentiment
# Active labels work normally
result = Result(sentiment="positive")
result.sentiment.description # "Expresses approval or satisfaction"
# Deprecated labels still parse but emit a DeprecationWarning
result = Result(sentiment="mixed") # warns: "Label 'mixed' is deprecated. Use 'NEUTRAL' instead."
# Retired labels are rejected — forces migration
Result(sentiment="ambiguous") # -> ValidationError
# Aliases silently resolve to their target
result = Result(sentiment="unclear") # resolves to AMBIGUOUS's alias -> handled
In any classification project, your label taxonomy will change. Labels get merged, split, renamed. Without lifecycle management you end up with dead labels in your schema, silent data quality regressions, and no migration path. LabelEnum makes taxonomy evolution a first-class concern.
# Introspect your taxonomy programmatically
Sentiment.active_labels() # [POSITIVE, NEGATIVE, NEUTRAL]
Sentiment.deprecated_labels() # [MIXED]
Sentiment.retired_labels() # [AMBIGUOUS]
Sentiment.schema_values() # ["positive", "negative", "neutral", "mixed"] (excludes retired)
Sentiment.alias_map() # {"unclear": AMBIGUOUS, "unknown": AMBIGUOUS}
Compatibility
pydantypes is designed as a complement to pydantic-extra-types. While pydantic-extra-types covers general-purpose types (colors, phone numbers, payment cards), pydantypes focuses on infrastructure and engineering identifiers.
For IBAN and BIC (banking identifiers), use schwifty which provides native Pydantic v2 support with __get_pydantic_core_schema__.
- Requires Pydantic v2.5+
- Supports Python 3.10–3.13
Architecture
See ARCHITECTURE.md for type patterns, conventions, and design decisions.
Development
# Clone and set up
git clone https://github.com/oborchers/pydantypes.git
cd pydantypes
make init
# Run checks
make check # lint + typecheck + test
make format # auto-format code
make test-cov # tests with coverage report
Disclaimer
pydantypes is an independent, community-maintained package and is not affiliated with or endorsed by Pydantic Services Inc.
License
MIT
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydantypes-1.0.0.tar.gz.
File metadata
- Download URL: pydantypes-1.0.0.tar.gz
- Upload date:
- Size: 155.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
02670c448a521a1020a512de72ef9175ded7ba7bb8d371598bbec68225a0125d
|
|
| MD5 |
e55b3d1ce363ba54d9979de41e915066
|
|
| BLAKE2b-256 |
4936709b1bd5ea9eb708c379d9bebcfe645b39dd635dbc592eef35d554f2ee32
|
Provenance
The following attestation bundles were made for pydantypes-1.0.0.tar.gz:
Publisher:
ci.yml on oborchers/pydantypes
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantypes-1.0.0.tar.gz -
Subject digest:
02670c448a521a1020a512de72ef9175ded7ba7bb8d371598bbec68225a0125d - Sigstore transparency entry: 1003346813
- Sigstore integration time:
-
Permalink:
oborchers/pydantypes@3af37b214f2c53a2ecc69d888d6824f084ed5086 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/oborchers
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@3af37b214f2c53a2ecc69d888d6824f084ed5086 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pydantypes-1.0.0-py3-none-any.whl.
File metadata
- Download URL: pydantypes-1.0.0-py3-none-any.whl
- Upload date:
- Size: 63.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95eb2755e946a544c823f08b368d9a52f767f746c5d644d03dbfc76c8f952a96
|
|
| MD5 |
62d96cb628cb28c16fa96786a3454d5d
|
|
| BLAKE2b-256 |
f6cb50506a2ed068a0411c74ca6d555e6d7228e525da4879a21a91dcf06b79ea
|
Provenance
The following attestation bundles were made for pydantypes-1.0.0-py3-none-any.whl:
Publisher:
ci.yml on oborchers/pydantypes
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pydantypes-1.0.0-py3-none-any.whl -
Subject digest:
95eb2755e946a544c823f08b368d9a52f767f746c5d644d03dbfc76c8f952a96 - Sigstore transparency entry: 1003346844
- Sigstore integration time:
-
Permalink:
oborchers/pydantypes@3af37b214f2c53a2ecc69d888d6824f084ed5086 -
Branch / Tag:
refs/tags/1.0.0 - Owner: https://github.com/oborchers
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
ci.yml@3af37b214f2c53a2ecc69d888d6824f084ed5086 -
Trigger Event:
push
-
Statement type: