johnbridges commited on
Commit
0fe181b
·
1 Parent(s): c8d97e7
Files changed (1) hide show
  1. config.py +37 -30
config.py CHANGED
@@ -1,27 +1,20 @@
1
  # app/config.py
2
  import json
3
  import os
4
- import re
5
  from functools import lru_cache
6
  from urllib.parse import quote
7
 
 
8
  APPSETTINGS_PATH = os.environ.get("APPSETTINGS_JSON", "appsettings.json")
9
 
10
 
11
  class Settings:
12
- """Simple settings object loaded from appsettings.json + env vars."""
13
  def __init__(self, data: dict):
14
  for k, v in data.items():
15
  setattr(self, k, v)
16
 
17
 
18
- def _to_upper_snake(name: str) -> str:
19
- """Convert CamelCase or mixedCase to UPPER_SNAKE_CASE."""
20
- s1 = re.sub("(.)([A-Z][a-z]+)", r"\1_\2", name)
21
- s2 = re.sub("([a-z0-9])([A-Z])", r"\1_\2", s1)
22
- return s2.upper()
23
-
24
-
25
  def _load_json(path):
26
  if not os.path.exists(path):
27
  return {}
@@ -30,35 +23,27 @@ def _load_json(path):
30
 
31
 
32
  def _replace_env_vars(d, parent_key=None):
 
 
 
33
  if isinstance(d, dict):
34
  return {k: _replace_env_vars(v, k) for k, v in d.items()}
35
  elif isinstance(d, str) and d.strip() == ".env":
36
- env_key = _to_upper_snake(parent_key or "")
37
  return os.environ.get(env_key)
38
  else:
39
  return d
40
 
41
 
42
- def _normalize_keys(d):
43
- """Recursively normalize dict keys to UPPER_SNAKE_CASE."""
44
- if isinstance(d, dict):
45
- return {_to_upper_snake(k): _normalize_keys(v) for k, v in d.items()}
46
- elif isinstance(d, list):
47
- return [_normalize_keys(i) for i in d]
48
- else:
49
- return d
50
-
51
-
52
- def build_amqp_url(cfg: dict):
53
- local = cfg.get("LOCAL_SYSTEM_URL")
54
  if not local:
55
  return None
56
- scheme = "amqps" if local.get("USE_TLS", True) else "amqp"
57
- host = local.get("RABBIT_HOST_NAME")
58
- port = local.get("RABBIT_PORT") or (5671 if scheme == "amqps" else 5672)
59
- user = local.get("RABBIT_USER_NAME")
60
- pwd = local.get("RABBIT_PASSWORD") or os.environ.get("RABBIT_PASSWORD")
61
- vhost = local.get("RABBIT_V_HOST") or "/"
62
  vhost_enc = quote(vhost, safe="")
63
  if not (host and user and pwd):
64
  return None
@@ -69,11 +54,33 @@ def build_amqp_url(cfg: dict):
69
  def get_settings() -> Settings:
70
  cfg = _load_json(APPSETTINGS_PATH)
71
  cfg = _replace_env_vars(cfg)
72
- cfg = _normalize_keys(cfg) # normalize AFTER env replacement
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  if not cfg.get("AMQP_URL"):
74
- amqp_url = build_amqp_url(cfg)
75
  if amqp_url:
76
  cfg["AMQP_URL"] = amqp_url
 
77
  return Settings(cfg)
78
 
79
 
 
1
  # app/config.py
2
  import json
3
  import os
 
4
  from functools import lru_cache
5
  from urllib.parse import quote
6
 
7
+
8
  APPSETTINGS_PATH = os.environ.get("APPSETTINGS_JSON", "appsettings.json")
9
 
10
 
11
  class Settings:
12
+ """Settings object with attribute access."""
13
  def __init__(self, data: dict):
14
  for k, v in data.items():
15
  setattr(self, k, v)
16
 
17
 
 
 
 
 
 
 
 
18
  def _load_json(path):
19
  if not os.path.exists(path):
20
  return {}
 
23
 
24
 
25
  def _replace_env_vars(d, parent_key=None):
26
+ """
27
+ Replace ".env" values with env var lookups using uppercase key name.
28
+ """
29
  if isinstance(d, dict):
30
  return {k: _replace_env_vars(v, k) for k, v in d.items()}
31
  elif isinstance(d, str) and d.strip() == ".env":
32
+ env_key = (parent_key or "").upper()
33
  return os.environ.get(env_key)
34
  else:
35
  return d
36
 
37
 
38
+ def _build_amqp_url(local: dict):
 
 
 
 
 
 
 
 
 
 
 
39
  if not local:
40
  return None
41
+ scheme = "amqps" if local.get("UseTls", True) else "amqp"
42
+ host = local.get("RabbitHostName")
43
+ port = local.get("RabbitPort") or (5671 if scheme == "amqps" else 5672)
44
+ user = local.get("RabbitUserName")
45
+ pwd = local.get("RabbitPassword") or os.environ.get("RABBIT_PASSWORD")
46
+ vhost = local.get("RabbitVHost") or "/"
47
  vhost_enc = quote(vhost, safe="")
48
  if not (host and user and pwd):
49
  return None
 
54
  def get_settings() -> Settings:
55
  cfg = _load_json(APPSETTINGS_PATH)
56
  cfg = _replace_env_vars(cfg)
57
+
58
+ # Flatten relevant LocalSystemUrl fields
59
+ local = cfg.get("LocalSystemUrl", {})
60
+ if local:
61
+ cfg["RABBIT_INSTANCE_NAME"] = local.get("RabbitInstanceName")
62
+ cfg["RABBIT_HOST_NAME"] = local.get("RabbitHostName")
63
+ cfg["RABBIT_PORT"] = local.get("RabbitPort")
64
+ cfg["RABBIT_USER_NAME"] = local.get("RabbitUserName")
65
+ cfg["RABBIT_PASSWORD"] = local.get("RabbitPassword") or os.environ.get("RABBIT_PASSWORD")
66
+ cfg["RABBIT_VHOST"] = local.get("RabbitVHost")
67
+ cfg["RABBIT_USE_TLS"] = local.get("UseTls")
68
+
69
+ # Map JSON keys to what Python code expects
70
+ cfg["SERVICE_ID"] = cfg.get("ServiceID")
71
+ cfg["RABBIT_ROUTING_KEY"] = cfg.get("RabbitRoutingKey")
72
+ cfg["RABBIT_EXCHANGE_TYPE"] = cfg.get("RabbitExhangeType") or "topic"
73
+ cfg["REDIS_URL"] = cfg.get("RedisUrl")
74
+ cfg["REDIS_SECRET"] = cfg.get("RedisSecret")
75
+ cfg["EXCHANGE_TYPES"] = cfg.get("EXCHANGE_TYPES", {}) # default empty dict
76
+ cfg["RABBIT_PREFETCH"] = cfg.get("RABBIT_PREFETCH", 1)
77
+
78
+ # Build AMQP_URL if not already provided
79
  if not cfg.get("AMQP_URL"):
80
+ amqp_url = _build_amqp_url(local)
81
  if amqp_url:
82
  cfg["AMQP_URL"] = amqp_url
83
+
84
  return Settings(cfg)
85
 
86