Skip to content

Commit bfc981f

Browse files
committed
redis: URL support for connection parameters
Make it possible to specify the Redis connection parameters via URL which can be supplied in the config file with key "url" (and leaving "host", "port", "password" and "db" empty/unspecified) or via environment variable PASSARI_WORKFLOW_REDIS_URL or REDIS_URL. The REDIS_URL environment variable is also used by the RQ workers by default so specifying it will also make RQ work without a config file. The default value if no connection parameters are given is to use db 0 on localhost (which is the same as RQ uses). Additionally provide a function "get_redis_url" so that passari-web-ui can use it to just get the URL without creating a Redis connection. Also tune the PostgreSQL URL handling to support similar environment variable based configuration via PASSARI_WORKFLOW_DB_URL or DATABASE_URL variables and fix the password escaping to use correct `quote` function instead of `quote_plus`. Note: The get_redis_connection used to accept a db index argument, but not anymore. Implementing override of the db index for the URLs would need some extra code, because the db index can be specified in various formats in the URL, but the argument was not used by any callers (in this code base or in passari-web-ui) so it's not worth it to implement.
1 parent af930a2 commit bfc981f

File tree

2 files changed

+35
-13
lines changed

2 files changed

+35
-13
lines changed

src/passari_workflow/db/connection.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1+
import os
2+
13
from passari_workflow.db import DBSession
24

35
from sqlalchemy import create_engine
46

5-
from urllib.parse import quote_plus
7+
from urllib.parse import quote
68

79
from passari_workflow.config import CONFIG
810

911

10-
def get_connection_uri():
12+
def get_connection_uri(*, default="error"):
1113
"""
1214
Get the connection URI used to connect to the database
1315
"""
@@ -21,12 +23,15 @@ def get_connection_uri():
2123
if url and not name:
2224
return url
2325
elif not url and not name:
26+
url = os.getenv("PASSARI_WORKFLOW_DB_URL", os.getenv("DATABASE_URL"))
27+
if url or (default != "error"):
28+
return url or default
2429
raise EnvironmentError("Either 'url' or 'name' is required for db")
2530
elif url and name:
2631
raise EnvironmentError("The db 'url' and 'name' are exclusive")
2732

2833
if user and host and port:
29-
return f"postgresql://{user}:{quote_plus(password)}@{host}:{port}/{name}"
34+
return f"postgresql://{user}:{quote(password)}@{host}:{port}/{name}"
3035
elif user or host or port or password:
3136
raise EnvironmentError(
3237
"If 'host' is given in PostgreSQL config,"
+27-10
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
1+
import os
2+
from urllib.parse import quote
3+
14
from passari_workflow.config import CONFIG
25

36
from redis import Redis
47

58

6-
def get_redis_connection(db=0):
9+
def get_redis_connection():
710
"""
811
Get Redis connection used for the workflow, distributed locks and other
912
miscellaneous tasks
1013
"""
11-
password = CONFIG["redis"].get("password", None)
12-
redis = Redis(
13-
host=CONFIG["redis"]["host"],
14-
port=CONFIG["redis"]["port"],
15-
db=db,
16-
password=password if password else None
17-
)
18-
19-
return redis
14+
redis_url = get_redis_url()
15+
return Redis.from_url(redis_url)
16+
17+
18+
def get_redis_url():
19+
redis_config = CONFIG.get("redis", {})
20+
url = redis_config.get("url")
21+
host = redis_config.get("host")
22+
port = redis_config.get("port")
23+
db = redis_config.get("db") or 0
24+
password = redis_config.get("password") or None
25+
26+
if not url and not host: # Get URL from environment
27+
return os.getenv(
28+
"PASSARI_WORKFLOW_REDIS_URL",
29+
os.getenv("REDIS_URL", "redis://localhost/0"),
30+
)
31+
elif url and (host or port or db or password):
32+
raise EnvironmentError("The 'url' config for Redis is exclusive")
33+
34+
password_part = f":{quote(password)}@" if password else ""
35+
port_part = f":{port}" if port else ""
36+
return f"redis://{password_part}{host}{port_part}/{db}"

0 commit comments

Comments
 (0)