diff --git a/.github/wordlist.txt b/.github/wordlist.txt
index b02328f8..ec4e1822 100644
--- a/.github/wordlist.txt
+++ b/.github/wordlist.txt
@@ -26,6 +26,7 @@ README.md
Redi
RediSearch
RediSearch
+RedisInsight
RedisJSON
SQLAlchemy
SSL
diff --git a/README.md b/README.md
index 8bfe6aa1..fc0135f0 100644
--- a/README.md
+++ b/README.md
@@ -352,7 +352,7 @@ redis_conn.set("hello", "world")
## 📚 Documentation
-The Redis OM documentation is available [here](docs/index.md).
+The Redis OM documentation is available at **[redis.github.io/redis-om-python](https://redis.github.io/redis-om-python/)**.
## ⛏️ Troubleshooting
@@ -366,7 +366,7 @@ Some advanced features of Redis OM rely on core features from two source availab
You can run these modules in your self-hosted Redis deployment, or you can use [Redis Enterprise][redis-enterprise-url], which includes both modules.
-To learn more, read [our documentation](docs/redis_modules.md).
+To learn more, read [our documentation](docs/redis_setup.md).
## Connecting to Azure Managed Redis with EntraID
diff --git a/docs/connections.md b/docs/connections.md
deleted file mode 100644
index adaa3c91..00000000
--- a/docs/connections.md
+++ /dev/null
@@ -1,100 +0,0 @@
-# Connecting to Redis
-
-You can control how Redis OM connects to Redis with the `REDIS_OM_URL` environment variable, or by manually constructing Redis client objects.
-
-## Environment Variable
-
-By default, Redis OM tries to connect to Redis on your localhost at port 6379. Most local install methods will result in Redis running at this location, in which case you don't need to do anything special for Redis OM to connect to Redis.
-
-However, if you configured Redis to run on a different port, or if you're using a remote Redis server, you'll need to set the `REDIS_OM_URL` environment variable.
-
-The `REDIS_OM_URL` environment variable follows the redis-py URL format:
-
- redis://[[username]:[password]]@localhost:6379/[database number]
-
-**NOTE:** The square brackets indicate an optional value and are not part of the URL format.
-
-The default connection is equivalent to the following `REDIS_OM_URL` environment variable:
-
- redis://localhost:6379
-
-**Note:** Indexing only works for data stored in Redis logical database 0. If you are using a different database number when connecting to Redis, you can expect the code to raise a `MigrationError` when you run the migrator.
-
-### Passwords and Usernames
-
-Redis can be configured with password protection and a "default" user, in which case you might connect using only the password.
-
-You can do so with Redis OM like this:
-
- redis://:your-password@localhost:6379
-
-If your Redis instance requires both a username and a password, you would include both in the URL:
-
- redis://your-username:your-password@localhost:6379
-
-### Database Number
-
-Redis databases are numbered, and the default is 0. You can leave off the database number to use the default database, or specify it.
-
-**Note:** Indexing only works for data stored in Redis logical database 0. If you are using a different database number when connecting to Redis, you can expect the code to raise a `MigrationError` when you run the migrator.
-
-### SSL Connections
-
-Use the "rediss" prefix for SSL connections:
-
- rediss://[[username]:[password]]@localhost:6379/0
-
-### Unix Domain Sockets
-
-Use the "unix" prefix to connect to Redis over Unix domain sockets:
-
- unix://[[username]:[password]]@/path/to/socket.sock?db=0
-
-### To Learn More
-
-To learn more about the URL format that Redis OM Python uses, consult the [redis-py URL documentation](https://redis-py.readthedocs.io/en/stable/#redis.Redis.from_url).
-
-**TIP:** The URL format is the same if you're using async or sync mode with Redis OM (i.e., importing `aredis_om` for async or `redis_om` for sync).
-
-## Connection Objects
-
-Aside from controlling connections via the `REDIS_OM_URL` environment variable, you can manually construct Redis client connections for a specific OM model class.
-
-**NOTE:** This method takes precedence over the `REDIS_OM_URL` environment variable.
-
-You can control the connection a specific model class should use by assigning an object to the *database* field of a model's _Meta_ object, like so:
-
-```python
-from redis_om import HashModel, get_redis_connection
-
-
-redis = get_redis_connection(port=6378)
-
-
-class Customer(HashModel):
- first_name: str
- last_name: str
- age: int
-
- class Meta:
- database = redis
-```
-
-The `get_redis_connection()` function is a Redis OM helper that passes keyword arguments to either `redis.asyncio.Redis.from_url()` or `redis.Redis.from_url()`, depending on whether you are using Redis OM in async or sync mode.
-
-You can also manually construct a client object:
-
-```python
-from redis import Redis
-
-from redis_om import HashModel
-
-
-class Customer(HashModel):
- first_name: str
- last_name: str
- age: int
-
- class Meta:
- database = Redis(port=6378)
-```
diff --git a/docs/fastapi_integration.md b/docs/fastapi_integration.md
index bbf9fd5b..2540134d 100644
--- a/docs/fastapi_integration.md
+++ b/docs/fastapi_integration.md
@@ -67,7 +67,26 @@ class Customer(HashModel):
bio: Optional[str]
-app = FastAPI()
+from contextlib import asynccontextmanager
+
+
+@asynccontextmanager
+async def lifespan(app: FastAPI):
+ # Startup: Initialize cache and Redis OM connection
+ r = redis.asyncio.from_url(REDIS_CACHE_URL, encoding="utf8",
+ decode_responses=True)
+ FastAPICache.init(RedisBackend(r), prefix="fastapi-cache")
+
+ # You can set the Redis OM URL using the REDIS_OM_URL environment
+ # variable, or by manually creating the connection using your model's
+ # Meta object.
+ Customer.Meta.database = get_redis_connection(url=REDIS_DATA_URL,
+ decode_responses=True)
+ yield
+ # Shutdown: cleanup if needed
+
+
+app = FastAPI(lifespan=lifespan)
@app.post("/customer")
@@ -90,19 +109,6 @@ async def get_customer(pk: str, request: Request, response: Response):
return Customer.get(pk)
except NotFoundError:
raise HTTPException(status_code=404, detail="Customer not found")
-
-
-@app.on_event("startup")
-async def startup():
- r = redis.asyncio.from_url(REDIS_CACHE_URL, encoding="utf8",
- decode_responses=True)
- FastAPICache.init(RedisBackend(r), prefix="fastapi-cache")
-
- # You can set the Redis OM URL using the REDIS_OM_URL environment
- # variable, or by manually creating the connection using your model's
- # Meta object.
- Customer.Meta.database = get_redis_connection(url=REDIS_DATA_URL,
- decode_responses=True)
```
## Testing the app
@@ -179,7 +185,26 @@ class Customer(HashModel):
bio: Optional[str]
-app = FastAPI()
+from contextlib import asynccontextmanager
+
+
+@asynccontextmanager
+async def lifespan(app: FastAPI):
+ # Startup: Initialize cache and Redis OM connection
+ r = redis.asyncio.from_url(REDIS_CACHE_URL, encoding="utf8",
+ decode_responses=True)
+ FastAPICache.init(RedisBackend(r), prefix="fastapi-cache")
+
+ # You can set the Redis OM URL using the REDIS_OM_URL environment
+ # variable, or by manually creating the connection using your model's
+ # Meta object.
+ Customer.Meta.database = get_redis_connection(url=REDIS_DATA_URL,
+ decode_responses=True)
+ yield
+ # Shutdown: cleanup if needed
+
+
+app = FastAPI(lifespan=lifespan)
@app.post("/customer")
@@ -202,19 +227,6 @@ async def get_customer(pk: str, request: Request, response: Response):
return await Customer.get(pk) # <- And, finally, one more await!
except NotFoundError:
raise HTTPException(status_code=404, detail="Customer not found")
-
-
-@app.on_event("startup")
-async def startup():
- r = redis.asyncio.from_url(REDIS_CACHE_URL, encoding="utf8",
- decode_responses=True)
- FastAPICache.init(RedisBackend(r), prefix="fastapi-cache")
-
- # You can set the Redis OM URL using the REDIS_OM_URL environment
- # variable, or by manually creating the connection using your model's
- # Meta object.
- Customer.Meta.database = get_redis_connection(url=REDIS_DATA_URL,
- decode_responses=True)
```
**NOTE:** The modules `redis_om` and `aredis_om` are identical in almost every
diff --git a/docs/getting_started.md b/docs/getting_started.md
index 01aa3a88..9925bd5e 100644
--- a/docs/getting_started.md
+++ b/docs/getting_started.md
@@ -81,14 +81,24 @@ The command to start Redis with Docker depends on the image you've chosen to use
**TIP:** The `-d` option in these examples runs Redis in the background, while `-p 6379:6379` makes Redis reachable at port 6379 on your localhost.
-#### Docker with the `redismod` image (recommended)
+#### Docker with Redis 8 (recommended)
- $ docker run -d -p 6379:6379 redislabs/redismod
+ $ docker run -d -p 6379:6379 redis:8
-### Docker with the `redis` image
+Redis 8 includes the Search and JSON capabilities needed for full Redis OM functionality.
+
+#### Docker with Redis Stack
+
+ $ docker run -d -p 6379:6379 redis/redis-stack
+
+Redis Stack also includes the Search and JSON capabilities.
+
+#### Docker with the basic `redis` image
$ docker run -d -p 6379:6379 redis
+**NOTE:** The basic Redis image does not include Search and JSON capabilities. You can still use Redis OM for data modeling and persistence, but `JsonModel` and the `find()` query interface won't work.
+
## Installing Redis OM
The recommended way to install Redis OM is with [Poetry](https://python-poetry.org/docs/). You can install Redis OM using Poetry with the following command:
@@ -239,9 +249,9 @@ try:
except ValidationError as e:
print(e)
"""
- ValidationError: 1 validation error for Customer
+ 1 validation error for Customer
bio
- field required (type=value_error.missing)
+ Field required [type=missing, input_value={'first_name': 'Andrew',..._date': datetime.date...}, input_type=dict]
"""
```
@@ -389,9 +399,9 @@ try:
except ValidationError as e:
print(e)
"""
- pydantic.error_wrappers.ValidationError: 1 validation error for Customer
+ 1 validation error for Customer
join_date
- invalid date format (type=value_error.date)
+ Input should be a valid date or datetime [type=date_from_datetime_parsing, ...]
"""
```
@@ -471,9 +481,9 @@ try:
except ValidationError as e:
print(e)
"""
- pydantic.error_wrappers.ValidationError: 1 validation error for Customer
+ 1 validation error for Customer
age
- Value is not a valid integer (type=type_error.integer)
+ Input should be a valid integer [type=int_type, ...]
"""
```
@@ -487,13 +497,22 @@ from pydantic import ValidationError
from redis_om import HashModel
+from typing import Annotated, Any
+from pydantic import GetCoreSchemaHandler
+from pydantic_core import CoreSchema, core_schema
+
+
class StrictDate(datetime.date):
+ """A strict date type that doesn't allow string coercion."""
+
@classmethod
- def __get_validators__(cls) -> 'CallableGenerator':
- yield cls.validate
+ def __get_pydantic_core_schema__(
+ cls, source_type: Any, handler: GetCoreSchemaHandler
+ ) -> CoreSchema:
+ return core_schema.no_info_plain_validator_function(cls.validate)
@classmethod
- def validate(cls, value: datetime.date, **kwargs) -> datetime.date:
+ def validate(cls, value: Any) -> datetime.date:
if not isinstance(value, datetime.date):
raise ValueError("Value must be a datetime.date object")
return value
@@ -516,14 +535,14 @@ try:
last_name="Brookins",
email="a@example.com",
join_date="2020-01-02", # <- A string shouldn't work now!
- age="38"
+ age=38
)
except ValidationError as e:
print(e)
"""
- pydantic.error_wrappers.ValidationError: 1 validation error for Customer
+ 1 validation error for Customer
join_date
- Value must be a datetime.date object (type=value_error)
+ Value error, Value must be a datetime.date object [type=value_error, ...]
"""
```
@@ -670,11 +689,10 @@ from pydantic import EmailStr
from redis_om import (
Field,
HashModel,
- Migrator
)
-class Customer(HashModel):
+class Customer(HashModel, index=True):
first_name: str
last_name: str = Field(index=True)
email: EmailStr
@@ -687,9 +705,8 @@ class Customer(HashModel):
# RediSearch module installed, we can run queries like the following.
# Before running queries, we need to run migrations to set up the
-# indexes that Redis OM will use. You can also use the `om migrate`
-# CLI tool for this!
-Migrator().run()
+# indexes that Redis OM will use. Run the `om migrate` CLI tool:
+# $ om migrate
# Find all customers with the last name "Brookins"
Customer.find(Customer.last_name == "Brookins").all()
@@ -710,16 +727,14 @@ For historical reasons, saving and querying Boolean values is not supported in `
you may store and query Boolean values using the `==` syntax:
```python
-from redis_om import (
- Field,
- JsonModel,
- Migrator
-)
+from redis_om import Field, JsonModel
+
-class Demo(JsonModel):
+class Demo(JsonModel, index=True):
b: bool = Field(index=True)
-Migrator().run()
+
+# Run migrations first with: om migrate
d = Demo(b=True)
d.save()
res = Demo.find(Demo.b == True)
diff --git a/docs/index.md b/docs/index.md
index 9edab572..8d703bcd 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -1,39 +1,85 @@
-# Redis OM for Python
+# Redis OM Python
-Welcome! This is the documentation for Redis OM Python.
+
+**Object mapping, and more, for Redis and Python.**
+
-**NOTE**: The documentation is a bit sparse at the moment but will continue to grow!
+[Get Started](getting_started.md){ .md-button .md-button--primary }
+[View on GitHub](https://github.com/redis/redis-om-python){ .md-button }
-## Getting Started
+---
-Read the Getting Started tutorial at [getting_started.md](getting_started.md).
+## Overview
-## Connecting to Redis
+Redis OM Python is a modern object mapping library for Redis that provides high-level abstractions to model and query Redis data with Python. Built on [Pydantic](https://docs.pydantic.dev/) for robust data validation, it supports both async and sync operations.
-Read about connecting to Redis at [connections.md](connections.md).
+## Features
-## Models and Fields
+
-Learn all about how to create model instances and define fields in [models.md](models.md).
+
+### :material-database: Hash & JSON Models
+Store data as Redis Hashes or JSON documents with automatic serialization.
+
-## Validating Data
+
+### :material-magnify: Powerful Queries
+Django-like ORM syntax with support for complex queries using RediSearch.
+
-Read about how to use Redis OM models to validate data at [validation.md](validation.md)
+
+### :material-check-circle: Pydantic Validation
+Full Pydantic v2 support for data validation and type safety.
+
-## Redis Modules
+
+### :material-lightning-bolt: Async & Sync
+Both async (`aredis_om`) and sync (`redis_om`) APIs available.
+
-Read how to get the RediSearch and RedisJSON modules at [redis_modules.md](redis_modules.md).
+
-## FastAPI Integration
+## Quick Start
-Redis OM is designed to integrate with the FastAPI web framework. See how this works at [fastapi_integration.md](fastapi_integration.md).
+### Installation
-## Migrations
+```bash
+pip install redis-om
+```
-Learn about schema and data migrations at [migrations.md](migrations.md).
+### Define a Model
-**Upgrading from 0.x to 1.0?** See the [0.x to 1.0 Migration Guide](migration_guide_0x_to_1x.md) for breaking changes and upgrade instructions.
+```python
+from redis_om import HashModel, Field
-## Error Messages
+class Customer(HashModel, index=True):
+ name: str = Field(index=True)
+ email: str = Field(index=True)
+ age: int = Field(index=True, sortable=True)
+```
-Get help with (some of) the error messages you might see from Redis OM: [errors.md](errors.md)
+### Create and Query
+
+```python
+# Create a customer
+customer = Customer(name="Alice", email="alice@example.com", age=30)
+customer.save()
+
+# Find customers by name
+results = Customer.find(Customer.name == "Alice").all()
+```
+
+## Requirements
+
+- **Python 3.10+**
+- **Redis 8** (recommended) or Redis Stack — see [Redis Setup](redis_setup.md)
+
+## Learn More
+
+- **[Getting Started](getting_started.md)** - Full tutorial to get up and running
+- **[Redis Setup](redis_setup.md)** - Choose and connect to Redis
+- **[Models](models.md)** - Deep dive into model definition and field types
+- **[FastAPI Integration](fastapi_integration.md)** - Build APIs with Redis OM
+
+!!! tip "Upgrading from 0.x?"
+ See the [Migration Guide](migration_guide_0x_to_1x.md) for breaking changes and upgrade instructions.
diff --git a/docs/migrations.md b/docs/migrations.md
index c89bbfb2..f1bf4fb7 100644
--- a/docs/migrations.md
+++ b/docs/migrations.md
@@ -86,11 +86,11 @@ Redis OM provides two approaches to schema migrations:
```python
# Before: Simple field
-class User(HashModel):
+class User(HashModel, index=True):
name: str = Field(index=True)
# After: Add sortable option
-class User(HashModel):
+class User(HashModel, index=True):
name: str = Field(index=True, sortable=True) # Schema change detected
```
@@ -366,7 +366,7 @@ Here's a complete workflow for adding a new feature with migrations:
1. **Modify Models**:
```python
-class User(HashModel):
+class User(HashModel, index=True):
name: str = Field(index=True)
email: str = Field(index=True)
created_at: datetime.datetime = Field(index=True, sortable=True) # New field
diff --git a/docs/redis_modules.md b/docs/redis_modules.md
deleted file mode 100644
index 71c0e872..00000000
--- a/docs/redis_modules.md
+++ /dev/null
@@ -1,30 +0,0 @@
-# Redis Modules
-
-Some advanced features of Redis OM, like rich query expressions and saving data as JSON, rely on core features from two source available Redis modules: **RediSearch** and **RedisJSON**.
-
-These modules are the "magic" behind the scenes:
-
-* RediSearch adds querying, indexing, and full-text search to Redis
-* RedisJSON adds the JSON data type to Redis
-
-## Why this is important
-
-Without RediSearch or RedisJSON installed, you can still use Redis OM to create declarative models backed by Redis.
-
-We'll store your model data in Redis as Hashes, and you can retrieve models using their primary keys. You'll also get all the validation features from Pydantic.
-
-So, what won't work without these modules?
-
-1. Without RedisJSON, you won't be able to nest models inside each other, like we did with the example model of a `Customer` model that has an `Address` embedded inside it.
-2. Without RediSearch, you won't be able to use our expressive queries to find models -- just primary keys.
-
-## So how do you get RediSearch and RedisJSON?
-
-You can use RediSearch and RedisJSON with your self-hosted Redis deployment. Just follow the instructions on installing the binary versions of the modules in their Quick Start Guides:
-
-- [RedisJSON Quick Start - Running Binaries](https://redis.io/docs/latest/develop/data-types/json/)
-- [RediSearch Quick Start - Running Binaries](https://redis.io/docs/latest/develop/get-started/document-database/)
-
-**NOTE**: Both of these modules' Quick Start Guides also have instructions on how to run the modules in Redis with Docker.
-
-Don't want to run Redis yourself? RediSearch and RedisJSON are also available on Redis Cloud. [Get started here.](https://redis.com/try-free/)
\ No newline at end of file
diff --git a/docs/redis_setup.md b/docs/redis_setup.md
new file mode 100644
index 00000000..cbe410bb
--- /dev/null
+++ b/docs/redis_setup.md
@@ -0,0 +1,113 @@
+# Redis Setup
+
+This page covers which Redis version to use and how to connect Redis OM to your Redis instance.
+
+## Choosing a Redis Version
+
+Redis OM Python works with **Redis 8** (recommended) or **Redis Stack**.
+
+### Redis 8 (Recommended)
+
+Redis 8 includes search and JSON capabilities built-in, so you don't need any additional modules. This is the simplest way to get started.
+
+**With Docker:**
+
+```bash
+docker run -p 6379:6379 redis:8
+```
+
+### Redis Stack
+
+[Redis Stack](https://redis.io/docs/latest/operate/oss_and_stack/install/install-stack/) bundles Redis with the RediSearch and RedisJSON modules. Use this if you need Redis 7.x compatibility.
+
+**With Docker:**
+
+```bash
+docker run -p 6379:6379 -p 8001:8001 redis/redis-stack
+```
+
+This also gives you access to RedisInsight at `http://localhost:8001` for visualizing your data.
+
+### Redis Cloud
+
+Don't want to run Redis yourself? [Redis Cloud](https://redis.com/try-free/) provides managed Redis with all the features Redis OM needs.
+
+## What Do You Need These Features For?
+
+Without Redis's search and JSON capabilities, you can still use Redis OM to create declarative models backed by Redis Hashes, retrieve models by primary key, and get Pydantic validation.
+
+The search and JSON features enable:
+
+1. **Rich queries** - Find models using expressive queries like `Customer.find(Customer.age > 30)`
+2. **Embedded models** - Nest models inside each other using `JsonModel` and `EmbeddedJsonModel`
+3. **Full-text search** - Search text fields with `full_text_search=True`
+
+## Connecting to Redis
+
+### Environment Variable
+
+By default, Redis OM connects to `localhost:6379`. To use a different Redis instance, set the `REDIS_OM_URL` environment variable:
+
+```bash
+export REDIS_OM_URL="redis://localhost:6379"
+```
+
+The URL format follows [redis-py conventions](https://redis-py.readthedocs.io/en/stable/#redis.Redis.from_url):
+
+```
+redis://[[username]:[password]]@host:port/[database]
+```
+
+**Examples:**
+
+```bash
+# Password only
+redis://:your-password@localhost:6379
+
+# Username and password
+redis://your-username:your-password@localhost:6379
+
+# SSL connection
+rediss://your-username:your-password@your-host:6379
+
+# Unix socket
+unix://:password@/path/to/socket.sock?db=0
+```
+
+!!! warning "Database 0 Required for Indexing"
+ Indexing only works with Redis logical database 0. Using a different database number will raise a `MigrationError` when running migrations.
+
+### Connection Objects
+
+You can also configure connections per-model using the `Meta` class:
+
+```python
+from redis_om import HashModel, get_redis_connection
+
+redis = get_redis_connection(port=6378)
+
+class Customer(HashModel):
+ first_name: str
+ last_name: str
+
+ class Meta:
+ database = redis
+```
+
+Or construct a client directly:
+
+```python
+from redis import Redis
+from redis_om import HashModel
+
+class Customer(HashModel):
+ first_name: str
+ last_name: str
+
+ class Meta:
+ database = Redis(host="localhost", port=6378)
+```
+
+!!! tip "Async and Sync"
+ The `get_redis_connection()` helper works for both async (`aredis_om`) and sync (`redis_om`) modes.
+
diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css
new file mode 100644
index 00000000..337b39c3
--- /dev/null
+++ b/docs/stylesheets/extra.css
@@ -0,0 +1,104 @@
+/* Custom styles for Redis OM Python documentation */
+
+/* Code block improvements */
+.highlight pre {
+ border-radius: 8px;
+}
+
+/* Improve readability of feature tables */
+table {
+ font-size: 0.9em;
+}
+
+table th {
+ background-color: var(--md-primary-fg-color--light);
+ color: var(--md-primary-bg-color);
+}
+
+/* Better spacing for navigation items */
+.md-nav__item--nested > .md-nav__link {
+ font-weight: 500;
+}
+
+/* Improve code snippet readability */
+.codehilite {
+ border-radius: 6px;
+ margin: 1em 0;
+}
+
+/* Better button styling for call-to-action */
+.md-button {
+ border-radius: 6px;
+}
+
+/* Improve admonition spacing */
+.admonition {
+ margin: 1.5em 0;
+}
+
+/* Hero section styling */
+.hero-section {
+ text-align: center;
+ padding: 2rem 0;
+}
+
+.hero-section h1 {
+ font-size: 2.5rem;
+ margin-bottom: 1rem;
+}
+
+/* Feature grid styling */
+.feature-grid {
+ display: grid;
+ grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
+ gap: 1.5rem;
+ margin: 2rem 0;
+}
+
+.feature-card {
+ background: var(--md-code-bg-color);
+ border-radius: 8px;
+ padding: 1.5rem;
+ border-left: 4px solid var(--md-accent-fg-color);
+}
+
+.feature-card h3 {
+ margin-top: 0;
+ color: var(--md-primary-fg-color);
+}
+
+/* Quick start section */
+.quick-start {
+ background: var(--md-code-bg-color);
+ border-radius: 8px;
+ padding: 1rem;
+ margin: 1rem 0;
+}
+
+/* Highlight important configuration blocks */
+.highlight .language-bash,
+.highlight .language-json,
+.highlight .language-yaml {
+ border-left: 4px solid var(--md-accent-fg-color);
+}
+
+/* Install command styling */
+.install-command {
+ background: var(--md-code-bg-color);
+ border-radius: 8px;
+ padding: 1rem;
+ margin: 1rem 0;
+ font-family: var(--md-code-font-family);
+}
+
+/* Badge styling for version info */
+.version-badge {
+ display: inline-block;
+ padding: 0.25rem 0.75rem;
+ background: var(--md-primary-fg-color);
+ color: var(--md-primary-bg-color);
+ border-radius: 4px;
+ font-size: 0.85rem;
+ font-weight: 500;
+}
+
diff --git a/docs/validation.md b/docs/validation.md
index a0f05dce..90861908 100644
--- a/docs/validation.md
+++ b/docs/validation.md
@@ -63,20 +63,13 @@ try:
except ValidationError as e:
print(e)
"""
- pydantic.error_wrappers.ValidationError: 1 validation error for Customer
- email
- value is not a valid email address (type=value_error.email)
+ 1 validation error for Customer
+ email
+ value is not a valid email address: An email address must have an @-sign. [type=value_error, ...]
"""
```
-As you can see, creating the `Customer` object generated the following error:
-
-```
- Traceback:
- pydantic.error_wrappers.ValidationError: 1 validation error for Customer
- email
- value is not a valid email address (type=value_error.email)
-```
+As you can see, creating the `Customer` object generated a validation error indicating that the email address is invalid.
We'll also get a validation error if we change a field on a model instance to an invalid value and then try to save the model:
@@ -114,20 +107,13 @@ try:
except ValidationError as e:
print(e)
"""
- pydantic.error_wrappers.ValidationError: 1 validation error for Customer
- email
- value is not a valid email address (type=value_error.email)
+ 1 validation error for Customer
+ email
+ value is not a valid email address: An email address must have an @-sign. [type=value_error, ...]
"""
```
-Once again, we get the validation error:
-
-```
- Traceback:
- pydantic.error_wrappers.ValidationError: 1 validation error for Customer
- email
- value is not a valid email address (type=value_error.email)
-```
+Once again, we get a validation error indicating the email address is invalid.
## Constrained Values
diff --git a/mkdocs.yml b/mkdocs.yml
index 7a27b093..34ee74a3 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -2,25 +2,107 @@ site_name: Redis OM Python
site_description: Object mapping, and more, for Redis and Python.
site_url: https://redis.github.io/redis-om-python/
repo_url: https://github.com/redis/redis-om-python
-repo_name: redis-om-python
+repo_name: redis/redis-om-python
+edit_uri: blob/main/docs
-# Source Markdown lives in the existing docs/ directory.
docs_dir: docs
-# Use the built-in MkDocs theme for now. This avoids extra dependencies.
theme:
- name: mkdocs
+ name: material
+ palette:
+ # Palette toggle for automatic mode
+ - media: "(prefers-color-scheme)"
+ toggle:
+ icon: material/brightness-auto
+ name: Switch to light mode
+
+ # Palette toggle for light mode
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ primary: red
+ accent: red
+ toggle:
+ icon: material/brightness-7
+ name: Switch to dark mode
+
+ # Palette toggle for dark mode
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ primary: red
+ accent: red
+ toggle:
+ icon: material/brightness-4
+ name: Switch to system preference
+
+ features:
+ - navigation.instant
+ - navigation.sections
+ - navigation.top
+ - navigation.footer
+ - toc.follow
+ - search.highlight
+ - search.share
+ - content.code.copy
+ - content.code.select
+ - content.action.edit
+ - content.action.view
+
+ icon:
+ repo: fontawesome/brands/github
+ edit: material/pencil
+ view: material/eye
+
+extra:
+ social:
+ - icon: fontawesome/brands/github
+ link: https://github.com/redis/redis-om-python
+ - icon: fontawesome/brands/python
+ link: https://pypi.org/project/redis-om/
nav:
- Home: index.md
- - Getting started: getting_started.md
- - Models: models.md
- - Connections: connections.md
- - Validation: validation.md
- - Redis modules: redis_modules.md
- - Migrations:
- - Overview: migrations.md
- - Upgrade 0.x to 1.x: migration_guide_0x_to_1x.md
- - FastAPI integration: fastapi_integration.md
- - Errors: errors.md
+ - Getting Started:
+ - Tutorial: getting_started.md
+ - Redis Setup: redis_setup.md
+ - User Guide:
+ - Models: models.md
+ - Validation: validation.md
+ - Migrations: migrations.md
+ - FastAPI Integration: fastapi_integration.md
+ - Reference:
+ - Errors: errors.md
+ - Release Notes 1.0: release_notes_1.0.md
+ - Upgrade Guide (0.x → 1.x): migration_guide_0x_to_1x.md
+
+plugins:
+ - search:
+ separator: '[\s\u200b\-_,:!=\[\]()"`/]+|\.(?!\d)|&[lg]t;|(?!\b)(?=[A-Z][a-z])'
+
+markdown_extensions:
+ - pymdownx.highlight:
+ anchor_linenums: true
+ line_spans: __span
+ pygments_lang_class: true
+ - pymdownx.inlinehilite
+ - pymdownx.snippets
+ - pymdownx.superfences
+ - admonition
+ - pymdownx.details
+ - pymdownx.tabbed:
+ alternate_style: true
+ - attr_list
+ - md_in_html
+ - pymdownx.emoji:
+ emoji_index: !!python/name:material.extensions.emoji.twemoji
+ emoji_generator: !!python/name:material.extensions.emoji.to_svg
+ - pymdownx.tasklist:
+ custom_checkbox: true
+ - toc:
+ permalink: true
+
+extra_css:
+ - stylesheets/extra.css
+
+copyright: |
+ © 2024 Redis
diff --git a/pyproject.toml b/pyproject.toml
index b91ed488..49d18fef 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -66,6 +66,7 @@ tox-pyenv = "^1.1.0"
codespell = "^2.2.0"
pre-commit = {version = "^4.3.0", python = ">=3.10"}
mkdocs = "^1.6.1"
+mkdocs-material = "^9.7.1"
[tool.poetry.scripts]
om = "aredis_om.cli.main:om"