Skip to content

Commit 6224072

Browse files
author
Andrew Brookins
committed
WIP on README - first draft
1 parent 703be3e commit 6224072

17 files changed

+197
-21
lines changed
File renamed without changes.

README.md

+187-17
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,193 @@
1-
# Redis Developer Python
1+
<h1 align="center">Redis Velvet</h1>
2+
<p align="center">
3+
<p align="center">
4+
Objecting mapping and more, for Redis.
5+
</p>
6+
</p>
27

3-
redis-developer-python is a high-level library containing useful Redis
4-
abstractions, like an ORM, rate limiter, and leaderboard.
8+
---
59

10+
[![Version][version-svg]][package-url]
11+
[![License][license-image]][license-url]
12+
[![Build Status][ci-svg]][ci-url]
613

7-
## ORM
14+
Redis Velvet is a library that helps you build modern Python applications with Redis.
815

9-
redis-developer-python includes an Object Redis Mapper.
16+
**Redis Velvet Python** | [Redis Velvet Node.js][redis-velvet-js] | [Redis Velvet Spring][redis-velvet-spring] | [Redis Velvet .NET][redis-velvet-dotnet]
1017

18+
<details>
19+
<summary><strong>Table of contents</strong></summary>
20+
21+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
22+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
23+
24+
25+
- [Why Redis Velvet?](#why)
26+
- [Getting started](#getting-started)
27+
- [Installation](#installation)
28+
- [Documentation](#documentation)
29+
- [Troubleshooting](#troubleshooting)
30+
- [Contributing](#contributing)
31+
- [License](#license)
32+
33+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
34+
35+
</details>
36+
37+
## ➡ Why Redis Velvet?
38+
39+
Redis Velvet is a library of high-level tools that help you build modern Python applications with Redis.
40+
41+
This *preview release* includes our first major component: a **declarative model class** backed by Redis.
42+
43+
## 🏁 Getting started
44+
45+
### Object Mapping
46+
47+
With Redis Velvet, you get powerful data modeling, validation, and query expressions with a small amount of code. Check out this example:
48+
49+
```python
50+
import datetime
51+
from typing import Optional
52+
53+
from redis_developer.model import (
54+
EmbeddedJsonModel,
55+
JsonModel,
56+
Field,
57+
)
58+
59+
class Address(EmbeddedJsonModel):
60+
address_line_1: str
61+
address_line_2: Optional[str]
62+
city: str = Field(index=True)
63+
state: str = Field(index=True)
64+
country: str
65+
postal_code: str = Field(index=True)
66+
67+
68+
class Customer(JsonModel):
69+
first_name: str = Field(index=True)
70+
last_name: str = Field(index=True)
71+
email: str = Field(index=True)
72+
join_date: datetime.date
73+
age: int = Field(index=True)
74+
bio: Optional[str] = Field(index=True, full_text_search=True,
75+
default="")
76+
77+
# Creates an embedded model.
78+
address: Address
79+
```
80+
81+
The example code defines `Address` and `Customer` models for use with a Redis database with the [RedisJSON](redis-json-url) module installed.
82+
83+
With these two classes defined, you can now:
84+
85+
* Validate data based on the model's type annotations using [Pydantic](pydantic-url)
86+
* Persist model instances to Redis as JSON
87+
* Instantiate model instances from Redis by primary key (a client-generated [ULID](ulid-url))
88+
* Query on any indexed fields in the models
89+
90+
### Querying
91+
Querying uses a rich expression syntax inspired by the Django ORM, SQLAlchemy, and Peewee.
92+
93+
Here are a few example queries that use the models we defined earlier:
94+
95+
```python
96+
# Find all customers with the last name "Brookins"
97+
Customer.find(Customer.last_name == "Brookins").all()
98+
99+
# Find all customers that do NOT have the last name "Brookins"
100+
Customer.find(Customer.last_name != "Brookins").all()
101+
102+
# Find all customers whose last name is "Brookins" OR whose age is
103+
# 100 AND whose last name is "Smith"
104+
Customer.find((Customer.last_name == "Brookins") | (
105+
Customer.age == 100
106+
) & (Customer.last_name == "Smith")).all()
107+
108+
# Find all customers who live in San Antonio, TX
109+
Customer.find(Customer.address.city == "San Antonio",
110+
Customer.address.state == "TX")
111+
```
112+
113+
Ready to learn more? Read the [getting started](docs/getting_started.md) guide or check out how to [add Redis Velvet to your FastAPI project](docs/integrating.md).
114+
115+
### RediSearch and RediJSON
116+
117+
Redis Velvet relies on core features from two source available Redis modules: **RediSearch** and **RedisJSON**.
118+
119+
RediSearch is a module that adds querying and full-text search to Redis, while RedisJSON adds support for the JSON data type to Redis.
120+
121+
#### Why this is important
122+
123+
Without RediSearch or RedisJSON installed, you can still use Redis Velvet 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.
124+
125+
So, what won't work without these modules?
126+
127+
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. This is because Redis Velvet will store your models in Redis as Hashes, which can't contain other container types like Lists or Hashes.
128+
2. Without RediSearch, you won't be able to use our expressive queries to find models -- just the primary key.
129+
130+
#### So how do you get RediSearch and RedisJSON?
131+
132+
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:
133+
134+
- [RedisJSON](https://oss.redis.com/redisjson/#download-and-running-binaries)
135+
- [RediSearch](https://oss.redis.com/redisearch/Quick_Start/#download_and_running_binaries)
136+
137+
RediSearch and RedisJSON are also available on all Redis Cloud managed services. [Get started here.](https://redis.com/try-free/)
138+
139+
## 💻 Installation
140+
141+
Installation is simple with `pip`, Poetry, or Pipenv.
142+
143+
```sh
144+
$ pip install redis-velvet
145+
146+
# Or, using Poetry
147+
$ poetry add redis-velvet
148+
```
149+
150+
## 📚 Documentation
151+
152+
Documentation is available [here](docs/index.md).
153+
154+
## ⛏️ Troubleshooting
155+
156+
If you run into trouble or have any questions, we're here to help!
157+
158+
First, check the [FAQ](docs/faq.md). If you don't find the answer there,
159+
hit us up on the [Redis Discord Server](http://discord.gg/redis).
160+
161+
162+
## ❤️ Contributing
163+
164+
We'd love your contributions!
165+
166+
**Bug reports** are especially helpful at this stage of the project. [You can open a big report on GitHub](https://github.com/redis-developer/redis-developer-python/issues/new).
167+
168+
You can also **contribute documentation** -- or just let us know if something needs more detail. [Open an issue on GitHub](https://github.com/redis-developer/redis-developer-python/issues/new) to get started.
169+
170+
## License
171+
172+
Redis Velvet is [MIT licensed][license-url].
173+
174+
<!-- Badges -->
175+
176+
[version-svg]: https://img.shields.io/pypi/v/redis-velvet?style=flat-square
177+
[package-url]: https://pypi.org/project/redis-velvet/
178+
[ci-svg]: https://img.shields.io/github/workflow/status/redis-developer/redis-developer-python/python?style=flat-square
179+
[ci-url]: https://github.com/redis-developer/redis-developer-python/actions/workflows/build.yml
180+
[license-image]: http://img.shields.io/badge/license-MIT-green.svg?style=flat-square
181+
[license-url]: LICENSE
182+
183+
<!-- Links -->
184+
185+
[redis-developer-website]: https://developer.redis.com
186+
[redis-velvet-js]: https://github.com/redis-developer/redis-velvet-js
187+
[redis-velvet-dotnet]: https://github.com/redis-developer/redis-velvet-dotnet
188+
[redis-velvet-spring]: https://github.com/redis-developer/redis-velvet-spring
189+
[redisearch-url]: https://oss.redis.com/redisearch/
190+
[redis-json-url]: https://oss.redis.com/redisjson/
191+
[pydantic-url]: https://github.com/samuelcolvin/pydantic
192+
[ulid-url]: https://github.com/ulid/spec
11193

12-
### Declarative model classes
13-
### Serialization and validation based on model classes
14-
### Save a model instance to Redis
15-
### Get a single model instance from Redis
16-
### Update a model instance in Redis
17-
### Batch/bulk insert and updates
18-
### Declarative “primary key”
19-
### Embedded models (JSON)
20-
### Exact-value queries on indexed fields
21-
### Declarative index creation and automatic index management (RediSearch)
22-
### Ad-hoc numeric range and full-text queries (RediSearch)
23-
### Aggregations (RediSearch)
File renamed without changes.

docs/getting_started.md

Whitespace-only changes.

docs/index.md

Whitespace-only changes.

docs/integrating.md

Whitespace-only changes.

redis_developer/orm/__init__.py renamed to redis_developer/model/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,6 @@
22
RedisModel,
33
HashModel,
44
JsonModel,
5+
EmbeddedJsonModel,
56
Field
67
)

redis_developer/model/cli/__init__.py

Whitespace-only changes.

redis_developer/orm/cli/migrate.py renamed to redis_developer/model/cli/migrate.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import click
2-
from redis_developer.orm.migrations.migrator import Migrator
2+
from redis_developer.om.migrations.migrator import Migrator
33

44

55
@click.command()
File renamed without changes.

redis_developer/model/migrations/__init__.py

Whitespace-only changes.

redis_developer/orm/migrations/migrator.py renamed to redis_developer/model/migrations/migrator.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from redis import ResponseError
88

99
from redis_developer.connections import get_redis_connection
10-
from redis_developer.orm.model import model_registry
10+
from redis_developer.om.model import model_registry
1111

1212
redis = get_redis_connection()
1313
log = logging.getLogger(__name__)

redis_developer/orm/model.py renamed to redis_developer/model/model.py

+5
Original file line numberDiff line numberDiff line change
@@ -1331,3 +1331,8 @@ def schema_for_type(cls, json_path: str, name: str, name_prefix: str, typ: Any,
13311331
raise sortable_tag_error
13321332
return schema
13331333
return ""
1334+
1335+
1336+
class EmbeddedJsonModel(JsonModel, abc.ABC):
1337+
class Meta:
1338+
embedded = True

redis_developer/orm/models.py renamed to redis_developer/model/models.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import abc
22
from typing import Optional
33

4-
from redis_developer.orm.model import JsonModel, HashModel
4+
from redis_developer.om.model import JsonModel, HashModel
55

66

77
class BaseJsonModel(JsonModel, abc.ABC):

redis_developer/orm/query_resolver.py renamed to redis_developer/model/query_resolver.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from collections import Sequence
22
from typing import Any, Dict, Mapping, Union, List
33

4-
from redis_developer.orm.model import Expression
4+
from redis_developer.om.model import Expression
55

66

77
class LogicalOperatorForListOfExpressions(Expression):

0 commit comments

Comments
 (0)