Skip to content

Conversation

@vilsonrodrigues
Copy link
Contributor

Summary

Implements 17 Pydantic-like validators using msgspec.Meta and custom str subclasses for common validation use cases:

Numeric Validators (8 types)

  • PositiveInt, NegativeInt, NonNegativeInt, NonPositiveInt
  • PositiveFloat, NegativeFloat, NonNegativeFloat, NonPositiveFloat
  • Uses msgspec.Meta for native C validation (maximum performance)

String Validators (9 types)

  • EmailStr - RFC 5321 email validation with regex
  • HttpUrl - HTTP/HTTPS URL validation only
  • AnyUrl - Any valid URL scheme (http, ftp, ws, etc.)
  • SecretStr - Masks sensitive data in repr/str (passwords, API keys)
  • PostgresDsn - PostgreSQL connection string validation
  • RedisDsn - Redis connection string validation
  • PaymentCardNumber - Luhn algorithm validation + automatic masking
  • FilePath - Validates path exists and is a file
  • DirectoryPath - Validates path exists and is a directory

Implementation Details

Architecture

  • Numeric types: Uses Annotated[int/float, msgspec.Meta(...)] for constraints
  • String types: Custom str subclasses with __new__ validation
  • Integration: Added dec_hook in settings.py for automatic type conversion
  • Environment variables: Enhanced _preprocess_env_value() to handle Annotated types

Key Features

  • Type-safe - Full msgspec integration with proper error messages
  • Performance - Uses msgspec.Meta for numeric constraints (C-level validation)
  • Security - SecretStr and PaymentCardNumber mask sensitive data
  • Compatibility - Familiar Pydantic-like API for easy migration

Testing

  • 71 new tests for validators (152 tests total)
  • All test categories:
    • 20 tests for numeric constraints
    • 6 tests for EmailStr
    • 6 tests for HttpUrl
    • 4 tests for AnyUrl
    • 8 tests for SecretStr
    • 5 tests for PostgresDsn
    • 4 tests for RedisDsn
    • 8 tests for PaymentCardNumber
    • 5 tests for FilePath
    • 5 tests for DirectoryPath

Test results: ✅ 152/152 passing
Lint: ✅ Clean

Documentation

Updated Files

  • README.md - New "Field Validators" section with examples and complete validator table
  • examples/06_validators.py - Comprehensive example demonstrating all 17 validators
  • Features section - Updated to highlight "17+ built-in validators"

Usage Example

from msgspec_ext import BaseSettings, EmailStr, HttpUrl, PositiveInt, SecretStr

class AppSettings(BaseSettings):
    # Email validation
    admin_email: EmailStr
    
    # URL validation
    api_url: HttpUrl
    
    # Numeric constraints
    port: PositiveInt  # Must be > 0
    max_workers: PositiveInt
    
    # Secret masking
    api_key: SecretStr  # Masked in logs
    
settings = AppSettings()
print(settings.api_key)  # Output: **********
print(settings.api_key.get_secret_value())  # Output: actual-key-value

Files Changed

  • src/msgspec_ext/types.py - New file (496 lines) - All validator implementations
  • tests/test_types.py - New file (684 lines) - Comprehensive test suite
  • examples/06_validators.py - New file (349 lines) - Usage examples
  • src/msgspec_ext/settings.py - Added dec_hook and Annotated type support
  • src/msgspec_ext/__init__.py - Export all validator types
  • README.md - Documentation updates

Performance Impact

No performance regression - validators only run when explicitly used:

  • Numeric validators use msgspec.Meta (C-level, zero overhead)
  • String validators only instantiated when field uses the type
  • Caching mechanisms unchanged

Next Steps (Future PRs)

This is Phase 1 of validators. Potential future enhancements:

  • Phase 2: Additional specialized validators (IpAddress, JsonStr, etc.)
  • Phase 3: Custom constraint combinators
  • Phase 4: Advanced validation features (cross-field validation, etc.)

🤖 Generated with Claude Code

vilsonrodrigues and others added 8 commits November 27, 2025 02:18
- Complete project structure overview
- Common commands and workflows
- Release process (always use ./scripts/release.sh)
- Architecture details and optimizations
- Linting, testing, and CI/CD guides
- Troubleshooting tips

This file provides context for Claude Code to work more effectively
with the project without repeating instructions.
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Implements Pydantic-like validators using msgspec.Meta and custom str subclasses:

**Numeric validators (8):**
- PositiveInt, NegativeInt, NonNegativeInt, NonPositiveInt
- PositiveFloat, NegativeFloat, NonNegativeFloat, NonPositiveFloat

**String validators (9):**
- EmailStr (RFC 5321 validation)
- HttpUrl (HTTP/HTTPS only), AnyUrl (any scheme)
- SecretStr (masks sensitive data in repr/str)
- PostgresDsn, RedisDsn (connection string validation)
- PaymentCardNumber (Luhn algorithm validation + masking)
- FilePath, DirectoryPath (filesystem validation)

**Implementation:**
- Numeric types use msgspec.Meta for native C validation
- String types use custom __new__ validation with proper error messages
- dec_hook in settings.py for automatic type conversion
- Enhanced _preprocess_env_value to handle Annotated types
- 71 comprehensive tests (152 total)

**Documentation:**
- Complete README section with examples and validator table
- New example file (06_validators.py) demonstrating all 17 validators
- Updated Features section to highlight validators

All tests passing ✅ (152/152)
Lint clean ✅

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
vilsonrodrigues and others added 3 commits December 3, 2025 09:28
**Ruff fixes:**
- Auto-format all files (3 files reformatted)
- Move tempfile import to top of file
- Remove unused variables in try/except blocks
- Add noqa directive for PLR0915 (too many statements in example main)
- Fix import ordering in test_types.py

**CodeQL fixes:**
- Add nosec comments for fake credentials in examples
- Mark example passwords/secrets as test data

All 152 tests passing ✅
Lint clean ✅

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Created CodeQL config to exclude examples/ folder from analysis.
Example files contain fake credentials for demonstration purposes only.

References:
- https://github.com/github/codeql/blob/main/.github/codeql/codeql-config.yml
- https://stackoverflow.com/questions/74030852/is-there-a-way-to-exclude-files-from-codeql-scanning-on-github

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
@vilsonrodrigues
Copy link
Contributor Author

/update

@github-actions
Copy link

github-actions bot commented Dec 3, 2025

ℹ️ Update commands are not supported for PRs from forks.

To update your branch, please run these commands locally:

git fetch upstream main
git merge upstream/main
git push

Or create a new PR from the same repository.

@vilsonrodrigues
Copy link
Contributor Author

/merge

@github-actions
Copy link

github-actions bot commented Dec 3, 2025

❌ Failed to merge PR: Resource not accessible by integration

@vilsonrodrigues vilsonrodrigues merged commit 6d81cfe into msgflux:main Dec 3, 2025
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant