Skip to content

Commit

Permalink
Merge pull request #105 from investigativedata/develop
Browse files Browse the repository at this point in the history
v0.1.5
  • Loading branch information
simonwoerpel committed Jun 18, 2024
2 parents 68d35b8 + b3da597 commit 3ec5b8c
Show file tree
Hide file tree
Showing 18 changed files with 987 additions and 1,134 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.1.4
current_version = 0.1.5
commit = True
tag = True
message = 🔖 Bump version: {current_version} → {new_version}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
path: ~/.cache/pre-commit
key: pre-commit-${{ runner.os }}-${{ env.PY }}-${{ hashFiles('.pre-commit-config.yaml') }}
- name: Install dependencies
run: poetry install --with dev
run: poetry install --with sql --with redis --with dev
- name: Run pre-commit hooks
run: poetry run pre-commit run
- name: Lint with flake8
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
all: clean install test

install:
poetry install --with dev
poetry install --with dev --with redis --with sql

lint:
poetry run flake8 anystore --count --select=E9,F63,F7,F82 --show-source --statistics
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.4
0.1.5
2 changes: 1 addition & 1 deletion anystore/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
]


__version__ = "0.1.4"
__version__ = "0.1.5"
7 changes: 4 additions & 3 deletions anystore/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
from anystore.settings import Settings
from anystore.store import get_store

cli = typer.Typer(no_args_is_help=True, pretty_exceptions_enable=False)
console = Console(stderr=True)

settings = Settings()
cli = typer.Typer(no_args_is_help=True, pretty_exceptions_enable=settings.debug)
console = Console(stderr=True)

state = {"uri": settings.uri, "pickle": False}

Expand All @@ -23,6 +22,8 @@ def __enter__(self):

def __exit__(self, e, msg, _):
if e is not None:
if settings.debug:
raise e
console.print(f"[red][bold]{e.__name__}[/bold]: {msg}[/red]")
raise typer.Exit(code=1)

Expand Down
5 changes: 4 additions & 1 deletion anystore/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ def smart_read(uri: Uri, mode: str | None = DEFAULT_MODE, **kwargs) -> Any:


def smart_write(
uri, content: bytes | str, mode: str | None = DEFAULT_WRITE_MODE, **kwargs
uri: Uri, content: bytes | str, mode: str | None = DEFAULT_WRITE_MODE, **kwargs
) -> None:
if uri == "-":
if isinstance(content, str):
content = content.encode()
with smart_open(uri, mode, **kwargs) as fh:
fh.write(content)
6 changes: 3 additions & 3 deletions anystore/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
log = logging.getLogger(__name__)


@lru_cache(1000)
@lru_cache(128)
def cached_from_uri(uri: Uri) -> str:
"""
Cache remote sources on runtime
Expand All @@ -30,7 +30,7 @@ class JsonMixin:

@classmethod
def from_json_str(cls, data: str, **kwargs) -> Self:
loaded = clean_dict({**orjson.loads(data), **kwargs})
loaded = clean_dict({**orjson.loads(data), **clean_dict(kwargs)})
return cls(**loaded)

@classmethod
Expand All @@ -46,7 +46,7 @@ class YamlMixin:

@classmethod
def from_yaml_str(cls, data: str, **kwargs) -> Self:
loaded = clean_dict({**yaml.safe_load(data), **kwargs})
loaded = clean_dict({**yaml.safe_load(data), **clean_dict(kwargs)})
return cls(**loaded)

@classmethod
Expand Down
5 changes: 5 additions & 0 deletions anystore/serialize.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ def from_store(value: bytes, serialization_mode: Mode | None = "auto") -> Any:
try:
return cloudpickle.loads(value)
except Exception:
if isinstance(value, bytes):
try:
return value.decode()
except UnicodeDecodeError:
pass
return value
4 changes: 4 additions & 0 deletions anystore/settings.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
from anystore.serialize import Mode

Expand All @@ -11,6 +12,9 @@ class Settings(BaseSettings):
serialization_mode: Mode | None = "auto"
raise_on_nonexist: bool = True

debug: bool = Field(alias="debug", default=False)
redis_debug: bool = Field(alias="redis_debug", default=False)


class SqlSettings(BaseSettings):
model_config = SettingsConfigDict(env_prefix="anystore_sql_")
Expand Down
19 changes: 15 additions & 4 deletions anystore/store/__init__.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
from functools import cache
from logging import getLogger
from urllib.parse import urlparse

from anystore.settings import Settings
from anystore.store.base import BaseStore
from anystore.store.fs import Store
from anystore.store.redis import RedisStore
from anystore.store.sql import SqlStore
from anystore.util import ensure_uri


log = getLogger(__name__)

settings = Settings()


Expand All @@ -26,9 +27,19 @@ def get_store(**kwargs) -> BaseStore:
uri = ensure_uri(uri)
parsed = urlparse(uri)
if parsed.scheme == "redis":
return RedisStore(**kwargs)
try:
from anystore.store.redis import RedisStore

return RedisStore(**kwargs)
except ImportError:
log.error("Install redis dependencies via `anystore[redis]`")
if "sql" in parsed.scheme:
return SqlStore(**kwargs)
try:
from anystore.store.sql import SqlStore

return SqlStore(**kwargs)
except ImportError:
log.error("Install sql dependencies via `anystore[sql]`")
return Store(**kwargs)


Expand Down
6 changes: 3 additions & 3 deletions anystore/store/redis.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,13 @@

from typing import Any, Generator
import logging
import os
from functools import cache

from banal import as_bool
import redis
import fakeredis

from anystore.exceptions import DoesNotExist
from anystore.settings import Settings
from anystore.store.base import BaseStore
from anystore.types import Uri, Value

Expand All @@ -21,7 +20,8 @@

@cache
def get_redis(uri: str) -> fakeredis.FakeStrictRedis | redis.Redis:
if as_bool(os.environ.get("REDIS_DEBUG")):
settings = Settings()
if settings.redis_debug:
con = fakeredis.FakeStrictRedis()
con.ping()
log.info("Redis connected: `fakeredis`")
Expand Down

0 comments on commit 3ec5b8c

Please sign in to comment.