Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add decrby to redis_client #275

Merged
merged 3 commits into from
Feb 14, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion .github/actions/waffles/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
docopt==0.6.2
Flask==2.3.3
markupsafe==2.1.4
git+https://github.com/cds-snc/[email protected].1#egg=notifications-utils
git+https://github.com/cds-snc/[email protected].2#egg=notifications-utils
15 changes: 15 additions & 0 deletions notifications_utils/clients/redis/redis_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,21 @@ def incrby(self, key, by, raise_exception=False):
except Exception as e:
self.__handle_exception(e, raise_exception, "incrby", key)

def decrby(
self,
key,
by,
raise_exception=False,
):
Fixed Show fixed Hide fixed
key = prepare_value(key)
if self.active:
try:
return self.redis_store.decrby(key, by)
except Exception as e:
self.__handle_exception(e, raise_exception, "decrby", key)

return None

def get(self, key, raise_exception=False):
key = prepare_value(key)
if self.active:
Expand Down
15 changes: 15 additions & 0 deletions notifications_utils/decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from flask import current_app
from functools import wraps


def requires_feature(flag):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very cool!

def decorator_feature_flag(func):
@wraps(func)
def wrapper(*args, **kwargs):
Fixed Show fixed Hide fixed
if current_app.config[flag]:
return func(*args, **kwargs)
return None

return wrapper

return decorator_feature_flag
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ include = '(notifications_utils|tests)/.*\.pyi?$'

[tool.poetry]
name = "notifications-utils"
version = "52.1.1"
version = "52.1.2"
description = "Shared python code for Notification - Provides logging utils etc."
authors = ["Canadian Digital Service"]
license = "MIT license"
Expand Down
18 changes: 18 additions & 0 deletions tests/test_decorators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from notifications_utils.decorators import requires_feature


@requires_feature("FEATURE_FLAG")
def decorated_function():
return "Feature enabled"


def test_requires_feature_enabled(mocker, app):
app.config["FEATURE_FLAG"] = True
result = decorated_function()
assert result == "Feature enabled"


def test_requires_feature_disabled(mocker, app):
app.config["FEATURE_FLAG"] = False
result = decorated_function()
assert result is None
5 changes: 5 additions & 0 deletions tests/test_redis_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,15 @@ def test_should_not_raise_exception_if_raise_set_to_false(app, caplog, mocker):
redis_client.redis_store.get = Mock(side_effect=Exception())
redis_client.redis_store.set = Mock(side_effect=Exception())
redis_client.redis_store.incr = Mock(side_effect=Exception())
redis_client.redis_store.decrby = Mock(side_effect=Exception())
redis_client.redis_store.pipeline = Mock(side_effect=Exception())
redis_client.redis_store.expire = Mock(side_effect=Exception())
redis_client.redis_store.delete = Mock(side_effect=Exception())
assert redis_client.get("get_key") is None
assert redis_client.set("set_key", "set_value") is None
assert redis_client.incr("incr_key") is None
assert redis_client.incrby("incrby_key", by=1) is None
assert redis_client.decrby("decrby_key", by=1) is None
assert redis_client.exceeded_rate_limit("rate_limit_key", 100, 100) is False
assert redis_client.expire("expire_key", 100) is None
assert redis_client.delete("delete_key") is None
Expand All @@ -79,6 +81,7 @@ def test_should_not_raise_exception_if_raise_set_to_false(app, caplog, mocker):
call.exception("Redis error performing set on set_key"),
call.exception("Redis error performing incr on incr_key"),
call.exception("Redis error performing incrby on incrby_key"),
call.exception("Redis error performing decrby on decrby_key"),
call.exception("Redis error performing rate-limit-pipeline on rate_limit_key"),
call.exception("Redis error performing expire on expire_key"),
call.exception("Redis error performing delete on delete_key"),
Expand Down Expand Up @@ -109,6 +112,8 @@ def test_should_raise_exception_if_raise_set_to_true(app):
with pytest.raises(Exception) as e:
redis_client.incrby("test", by=1, raise_exception=True)
assert str(e.value) == "incrby failed"
with pytest.raises(Exception) as e:
redis_client.decrby("test", by=1, raise_exception=True)
with pytest.raises(Exception) as e:
redis_client.exceeded_rate_limit("test", 100, 200, raise_exception=True)
assert str(e.value) == "pipeline failed"
Expand Down
Loading