Skip to content

Commit b2c2dd9

Browse files
author
Andrew Brookins
committed
WIP on async - test failure due to closed event loop
1 parent 0f9f7aa commit b2c2dd9

22 files changed

+348
-190
lines changed

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
NAME := redis_developer
1+
NAME := redis_om
22
INSTALL_STAMP := .install.stamp
33
POETRY := $(shell command -v poetry 2> /dev/null)
44

README.md

+9-9
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Check out this example:
5252
import datetime
5353
from typing import Optional
5454

55-
from redis_developer.model import (
55+
from redis_om.model import (
5656
EmbeddedJsonModel,
5757
JsonModel,
5858
Field,
@@ -172,9 +172,9 @@ Don't want to run Redis yourself? RediSearch and RedisJSON are also available on
172172

173173
We'd love your contributions!
174174

175-
**Bug reports** are especially helpful at this stage of the project. [You can open a bug report on GitHub](https://github.com/redis-developer/redis-developer-python/issues/new).
175+
**Bug reports** are especially helpful at this stage of the project. [You can open a bug report on GitHub](https://github.com/redis-om/redis-om-python/issues/new).
176176

177-
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.
177+
You can also **contribute documentation** -- or just let us know if something needs more detail. [Open an issue on GitHub](https://github.com/redis-om/redis-om-python/issues/new) to get started.
178178

179179
## License
180180

@@ -184,17 +184,17 @@ Redis OM is [MIT licensed][license-url].
184184

185185
[version-svg]: https://img.shields.io/pypi/v/redis-om?style=flat-square
186186
[package-url]: https://pypi.org/project/redis-om/
187-
[ci-svg]: https://img.shields.io/github/workflow/status/redis-developer/redis-developer-python/python?style=flat-square
188-
[ci-url]: https://github.com/redis-developer/redis-developer-python/actions/workflows/build.yml
187+
[ci-svg]: https://img.shields.io/github/workflow/status/redis-om/redis-om-python/python?style=flat-square
188+
[ci-url]: https://github.com/redis-om/redis-om-python/actions/workflows/build.yml
189189
[license-image]: http://img.shields.io/badge/license-MIT-green.svg?style=flat-square
190190
[license-url]: LICENSE
191191

192192
<!-- Links -->
193193

194-
[redis-developer-website]: https://developer.redis.com
195-
[redis-om-js]: https://github.com/redis-developer/redis-om-js
196-
[redis-om-dotnet]: https://github.com/redis-developer/redis-om-dotnet
197-
[redis-om-spring]: https://github.com/redis-developer/redis-om-spring
194+
[redis-om-website]: https://developer.redis.com
195+
[redis-om-js]: https://github.com/redis-om/redis-om-js
196+
[redis-om-dotnet]: https://github.com/redis-om/redis-om-dotnet
197+
[redis-om-spring]: https://github.com/redis-om/redis-om-spring
198198
[redisearch-url]: https://oss.redis.com/redisearch/
199199
[redis-json-url]: https://oss.redis.com/redisjson/
200200
[pydantic-url]: https://github.com/samuelcolvin/pydantic

build.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import unasync
2+
3+
4+
def build(setup_kwargs):
5+
setup_kwargs.update(
6+
{"cmdclass": {'build_py': unasync.cmdclass_build_py(rules=[
7+
unasync.Rule("/aredis_om/", "/redis_om/"),
8+
unasync.Rule("/aredis_om/tests/", "/redis_om/tests/", additional_replacements={"aredis_om": "redis_om"}),
9+
])}}
10+
)

poetry.lock

+31-1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
[tool.poetry]
2-
name = "redis-developer"
2+
name = "redis-om"
33
version = "0.1.0"
44
description = "A high-level library containing useful Redis abstractions and tools, like an ORM and leaderboard."
55
authors = ["Andrew Brookins <[email protected]>"]
66
license = "MIT"
7+
build = "build.py"
78

89
[tool.poetry.dependencies]
910
python = "^3.8"
@@ -30,10 +31,11 @@ bandit = "^1.7.0"
3031
coverage = "^6.0.2"
3132
pytest-cov = "^3.0.0"
3233
pytest-xdist = "^2.4.0"
33-
34+
unasync = "^0.5.0"
35+
pytest-asyncio = "^0.16.0"
3436

3537
[tool.poetry.scripts]
36-
migrate = "redis_developer.orm.cli.migrate:migrate"
38+
migrate = "redis_om.orm.cli.migrate:migrate"
3739

3840
[build-system]
3941
requires = ["poetry-core>=1.0.0"]
File renamed without changes.
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,28 @@
11
import os
2+
from typing import Union
23

34
import dotenv
5+
import aioredis
46
import redis
5-
7+
from redis_om.unasync_util import ASYNC_MODE
68

79
dotenv.load_dotenv()
810

911
URL = os.environ.get("REDIS_OM_URL", None)
12+
if ASYNC_MODE:
13+
client = aioredis.Redis
14+
else:
15+
client = redis.Redis
1016

1117

12-
def get_redis_connection(**kwargs) -> redis.Redis:
18+
def get_redis_connection(**kwargs) -> Union[aioredis.Redis, redis.Redis]:
1319
# If someone passed in a 'url' parameter, or specified a REDIS_OM_URL
1420
# environment variable, we'll create the Redis client from the URL.
1521
url = kwargs.pop("url", URL)
1622
if url:
17-
return redis.from_url(url, **kwargs)
23+
return client.from_url(url, **kwargs)
1824

1925
# Decode from UTF-8 by default
2026
if "decode_responses" not in kwargs:
2127
kwargs["decode_responses"] = True
22-
return redis.Redis(**kwargs)
28+
return client(**kwargs)
File renamed without changes.

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import click
22

3-
from redis_developer.model.migrations.migrator import Migrator
3+
from redis_om.model.migrations.migrator import Migrator
44

55

66
@click.command()
7-
@click.option("--module", default="redis_developer")
7+
@click.option("--module", default="redis_om")
88
def migrate(module):
99
migrator = Migrator(module)
1010

File renamed without changes.

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

+34-29
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,14 @@
22
import logging
33
from dataclasses import dataclass
44
from enum import Enum
5-
from typing import Optional
5+
from typing import Optional, Union
66

7-
from redis import ResponseError
7+
from redis import ResponseError, Redis
8+
from aioredis import ResponseError as AResponseError, Redis as ARedis
89

9-
from redis_developer.connections import get_redis_connection
10-
from redis_developer.model.model import model_registry
10+
from redis_om.model.model import model_registry
1111

1212

13-
redis = get_redis_connection()
1413
log = logging.getLogger(__name__)
1514

1615

@@ -43,12 +42,12 @@ def schema_hash_key(index_name):
4342
return f"{index_name}:hash"
4443

4544

46-
def create_index(index_name, schema, current_hash):
45+
async def create_index(redis: Union[Redis, ARedis], index_name, schema, current_hash):
4746
try:
48-
redis.execute_command(f"ft.info {index_name}")
49-
except ResponseError:
50-
redis.execute_command(f"ft.create {index_name} {schema}")
51-
redis.set(schema_hash_key(index_name), current_hash)
47+
await redis.execute_command(f"ft.info {index_name}")
48+
except (ResponseError, AResponseError):
49+
await redis.execute_command(f"ft.create {index_name} {schema}")
50+
await redis.set(schema_hash_key(index_name), current_hash)
5251
else:
5352
log.info("Index already exists, skipping. Index hash: %s", index_name)
5453

@@ -65,34 +64,38 @@ class IndexMigration:
6564
schema: str
6665
hash: str
6766
action: MigrationAction
67+
redis: Union[Redis, ARedis]
6868
previous_hash: Optional[str] = None
6969

70-
def run(self):
70+
async def run(self):
7171
if self.action is MigrationAction.CREATE:
72-
self.create()
72+
await self.create()
7373
elif self.action is MigrationAction.DROP:
74-
self.drop()
74+
await self.drop()
7575

76-
def create(self):
76+
async def create(self):
7777
try:
78-
return create_index(self.index_name, self.schema, self.hash)
78+
await create_index(self.redis, self.index_name, self.schema, self.hash)
7979
except ResponseError:
8080
log.info("Index already exists: %s", self.index_name)
8181

82-
def drop(self):
82+
async def drop(self):
8383
try:
84-
redis.execute_command(f"FT.DROPINDEX {self.index_name}")
84+
await self.redis.execute_command(f"FT.DROPINDEX {self.index_name}")
8585
except ResponseError:
8686
log.info("Index does not exist: %s", self.index_name)
8787

8888

8989
class Migrator:
90-
def __init__(self, module=None):
91-
# Try to load any modules found under the given path or module name.
92-
if module:
93-
import_submodules(module)
94-
90+
def __init__(self, redis: Union[Redis, ARedis], module=None):
91+
self.module = module
9592
self.migrations = []
93+
self.redis = redis
94+
95+
async def run(self):
96+
# Try to load any modules found under the given path or module name.
97+
if self.module:
98+
import_submodules(self.module)
9699

97100
for name, cls in model_registry.items():
98101
hash_key = schema_hash_key(cls.Meta.index_name)
@@ -104,20 +107,21 @@ def __init__(self, module=None):
104107
current_hash = hashlib.sha1(schema.encode("utf-8")).hexdigest() # nosec
105108

106109
try:
107-
redis.execute_command("ft.info", cls.Meta.index_name)
108-
except ResponseError:
110+
await self.redis.execute_command("ft.info", cls.Meta.index_name)
111+
except (ResponseError, AResponseError):
109112
self.migrations.append(
110113
IndexMigration(
111114
name,
112115
cls.Meta.index_name,
113116
schema,
114117
current_hash,
115118
MigrationAction.CREATE,
119+
self.redis
116120
)
117121
)
118122
continue
119123

120-
stored_hash = redis.get(hash_key)
124+
stored_hash = self.redis.get(hash_key)
121125
schema_out_of_date = current_hash != stored_hash
122126

123127
if schema_out_of_date:
@@ -129,7 +133,8 @@ def __init__(self, module=None):
129133
schema,
130134
current_hash,
131135
MigrationAction.DROP,
132-
stored_hash,
136+
self.redis,
137+
stored_hash
133138
)
134139
)
135140
self.migrations.append(
@@ -139,12 +144,12 @@ def __init__(self, module=None):
139144
schema,
140145
current_hash,
141146
MigrationAction.CREATE,
142-
stored_hash,
147+
self.redis,
148+
stored_hash
143149
)
144150
)
145151

146-
def run(self):
147152
# TODO: Migration history
148153
# TODO: Dry run with output
149154
for migration in self.migrations:
150-
migration.run()
155+
await migration.run()

0 commit comments

Comments
 (0)