Skip to content
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"permissions": {
"allow": [
"Bash(nox:*)",
"WebFetch(domain:github.com)",
"Bash(find:*)",
"Bash(grep:*)",
"Bash(poetry run pytest:*)",
"Bash(poetry run:*)",
"Bash(python test:*)",
"Bash(mkdir:*)",
"Bash(ruff check:*)",
"WebFetch(domain:docs.pydantic.dev)"
],
"deny": []
}
}
106 changes: 106 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Common Commands

### Testing
- `poetry run nox -s tests`: Run full test suite
- `poetry run nox -s "tests-3.12"`: Run tests with specific Python version
- `poetry run pytest tests/`: Run tests with pytest directly
- `poetry run pytest tests/path/to/test.py::test_function`: Run specific test

### Code Quality
- `poetry run ruff check`: Run linting (configured in pyproject.toml)
- `poetry run ruff format`: Format code
- `poetry run mypy strawberry/`: Type checking
- `poetry run pyright`: Alternative type checker

### Development
- `poetry install --with integrations`: Install dependencies
- `poetry run strawberry server app`: Run development server
- `poetry run strawberry export-schema`: Export GraphQL schema
- `poetry run strawberry codegen`: Generate TypeScript types

## Common Development Practices
- Always use poetry to run python tasks and tests
- Use `poetry run` prefix for all Python commands to ensure correct virtual environment

## Architecture Overview

Strawberry is a Python GraphQL library that uses a **decorator-based, code-first approach** built on Python's type system and dataclasses.

### Core Components

**Schema Layer** (`strawberry/schema/`):
- `schema.py`: Main Schema class for execution and validation
- `schema_converter.py`: Converts Strawberry types to GraphQL-core types
- `config.py`: Configuration management

**Type System** (`strawberry/types/`):
- `object_type.py`: Core decorators (`@type`, `@input`, `@interface`)
- `field.py`: Field definitions and `@field` decorator
- `enum.py`, `scalar.py`, `union.py`: GraphQL type implementations

**Extensions System** (`strawberry/extensions/`):
- `base_extension.py`: Base SchemaExtension class with lifecycle hooks
- `tracing/`: Built-in tracing (Apollo, DataDog, OpenTelemetry)
- Plugin ecosystem for caching, security, performance

**HTTP Layer** (`strawberry/http/`):
- Framework-agnostic HTTP handling
- Base classes for framework integrations
- GraphQL IDE integration

### Framework Integrations

Each framework integration (FastAPI, Django, Flask, etc.) inherits from base HTTP classes and implements:
- Request/response adaptation
- Context management
- WebSocket handling for subscriptions
- Framework-specific middleware

### Key Patterns

1. **Decorator-First Design**: Uses `@type`, `@field`, `@mutation` decorators
2. **Dataclass Foundation**: All GraphQL types are Python dataclasses
3. **Type Annotation Integration**: Automatic GraphQL type inference from Python types
4. **Lazy Type Resolution**: Handles forward references and circular dependencies
5. **Schema Converter Pattern**: Clean separation between Strawberry and GraphQL-core types

### Federation Support

Built-in Apollo Federation support via `strawberry.federation` with automatic `_service` and `_entities` field generation.

## Development Guidelines

### Type System
- Use Python type annotations for GraphQL type inference
- Leverage `@strawberry.type` for object types
- Use `@strawberry.field` for custom resolvers
- Support for generics and complex type relationships

### Extension Development
- Extend `SchemaExtension` for schema-level extensions
- Use `FieldExtension` for field-level middleware
- Hook into execution lifecycle: `on_operation`, `on_parse`, `on_validate`, `on_execute`

### Testing Patterns
- Tests are organized by module in `tests/`
- Use `strawberry.test.client` for GraphQL testing
- Integration tests for each framework in respective directories
- Snapshot testing for schema output

### Code Organization
- Main API surface in `strawberry/__init__.py`
- Experimental features in `strawberry/experimental/`
- Framework integrations in separate packages
- CLI commands in `strawberry/cli/`

## Important Files

- `strawberry/__init__.py`: Main API exports
- `strawberry/schema/schema.py`: Core schema execution
- `strawberry/types/object_type.py`: Core decorators
- `noxfile.py`: Test configuration
- `pyproject.toml`: Project configuration and dependencies
104 changes: 104 additions & 0 deletions PLAN.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# ✅ COMPLETED: First-class Pydantic Support Implementation

Plan to add first class support for Pydantic, similar to how it was outlined here:

https://github.com/strawberry-graphql/strawberry/issues/2181

## Original Goal

We have already support for pydantic, but it is experimental, and works like this:

```python
class UserModel(BaseModel):
age: int


@strawberry.experimental.pydantic.type(UserModel, all_fields=True)
class User: ...
```

The issue is that we need to create a new class that for the GraphQL type,
it would be nice to remove this requirement and do this instead:

```python
@strawberry.pydantic.type
class UserModel(BaseModel):
age: int
```

This means we can directly pass a pydantic model to the strawberry pydantic type decorator.

## ✅ Implementation Status: COMPLETED

### ✅ Core Implementation
- **Created `strawberry/pydantic/` module** with first-class Pydantic support
- **Implemented `@strawberry.pydantic.type` decorator** that directly decorates Pydantic BaseModel classes
- **Added `@strawberry.pydantic.input` decorator** for GraphQL input types
- **Added `@strawberry.pydantic.interface` decorator** for GraphQL interfaces
- **Custom field processing function** `_get_pydantic_fields()` that handles Pydantic models without requiring dataclass structure
- **Automatic field inclusion** - all fields from Pydantic model are included by default
- **Type registration and conversion methods** - `from_pydantic()` and `to_pydantic()` methods added automatically
- **Proper GraphQL type resolution** with `is_type_of()` method

### ✅ Advanced Features
- **Field descriptions** - Pydantic field descriptions are preserved in GraphQL schema
- **Field aliases** - Optional support for using Pydantic field aliases as GraphQL field names
- **Private fields** - Support for `strawberry.Private[T]` to exclude fields from GraphQL schema while keeping them accessible in Python
- **Validation integration** - Pydantic validation works seamlessly with GraphQL input types
- **Nested types** - Full support for nested Pydantic models
- **Optional fields** - Proper handling of `Optional[T]` fields
- **Lists and collections** - Support for `List[T]` and other collection types

### ✅ Files Created/Modified
- `strawberry/pydantic/__init__.py` - Main module exports
- `strawberry/pydantic/fields.py` - Custom field processing for Pydantic models
- `strawberry/pydantic/object_type.py` - Core decorators (type, input, interface)
- `strawberry/__init__.py` - Updated to export new pydantic module
- `tests/pydantic/test_basic.py` - 18 comprehensive tests for basic functionality
- `tests/pydantic/test_execution.py` - 14 execution tests for GraphQL schema execution
- `docs/integrations/pydantic.md` - Complete documentation with examples and migration guide

### ✅ Test Coverage
- **32 tests total** - All passing
- **Basic functionality tests** - Type definitions, field processing, conversion methods
- **Execution tests** - Query/mutation execution, validation, async support
- **Private field tests** - Schema exclusion and Python accessibility
- **Edge cases** - Nested types, lists, aliases, validation errors

### ✅ Key Features Implemented
1. **Direct BaseModel decoration**: `@strawberry.pydantic.type` directly on Pydantic models
2. **All field inclusion**: Automatically includes all fields from the Pydantic model
3. **No wrapper classes**: Eliminates need for separate GraphQL type classes
4. **Full type system support**: Types, inputs, and interfaces
5. **Pydantic v2+ compatibility**: Works with latest Pydantic versions
6. **Clean API**: Much simpler than experimental integration
7. **Backward compatibility**: Experimental integration continues to work

### ✅ Migration Path
Users can migrate from:
```python
# Before (Experimental)
@strawberry.experimental.pydantic.type(UserModel, all_fields=True)
class User:
pass
```

To:
```python
# After (First-class)
@strawberry.pydantic.type
class User(BaseModel):
name: str
age: int
```

### ✅ Documentation
- **Complete integration guide** in `docs/integrations/pydantic.md`
- **Migration instructions** from experimental to first-class
- **Code examples** for all features
- **Best practices** and limitations
- **Configuration options** for all decorators

## Status: ✅ IMPLEMENTATION COMPLETE

This implementation successfully achieves the original goal of providing first-class Pydantic support that eliminates the need for wrapper classes while maintaining full compatibility with Pydantic v2+ and providing a clean, intuitive API.
3 changes: 3 additions & 0 deletions RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Release type: minor

TODO
Loading
Loading