morpheuslord commited on
Commit
85c5132
Β·
1 Parent(s): 1ca7c98

Add training pipeline

Browse files
Files changed (1) hide show
  1. app.py +44 -24
app.py CHANGED
@@ -4,16 +4,9 @@ Runs train_and_upgrade.py in the background, streams logs live,
4
  and exports the upgraded model to morpheuslord/rewrite on completion.
5
  """
6
 
7
- # ── Jinja2 / Gradio 4.44.0 compatibility patch ───────────────────────────────
8
- # Jinja2 >= 3.1.4 builds an LRU cache key that contains a dict (and sometimes
9
- # a list inside that dict), both of which are unhashable β†’ TypeError on every
10
- # request. Fix: wrap LRUCache.__getitem__ / __setitem__ / .get so that any
11
- # unhashable element is recursively converted to a hashable equivalent before
12
- # the key hits the underlying dict. Key rules:
13
- # dict β†’ frozenset of (k, v) pairs
14
- # list β†’ tuple (NOT list β€” list is still unhashable!)
15
- # tuple β†’ tuple with each element also made hashable
16
- # other β†’ unchanged
17
  def _patch_jinja2_lru_cache():
18
  import jinja2.utils as _ju
19
 
@@ -21,37 +14,64 @@ def _patch_jinja2_lru_cache():
21
  if isinstance(obj, dict):
22
  return frozenset((_make_hashable(k), _make_hashable(v)) for k, v in obj.items())
23
  if isinstance(obj, (list, tuple)):
24
- return tuple(_make_hashable(i) for i in obj) # always tuple, never list
25
  return obj
26
 
27
- _orig_getitem = _ju.LRUCache.__getitem__
28
- _orig_setitem = _ju.LRUCache.__setitem__
29
- _orig_get = _ju.LRUCache.get
30
 
31
- def _safe_getitem(self, key):
32
  try:
33
- return _orig_getitem(self, key)
34
  except TypeError:
35
- return _orig_getitem(self, _make_hashable(key))
36
 
37
- def _safe_setitem(self, key, value):
38
  try:
39
- _orig_setitem(self, key, value)
40
  except TypeError:
41
- _orig_setitem(self, _make_hashable(key), value)
42
 
43
- def _safe_get(self, key, default=None):
44
  try:
45
  return _orig_get(self, key, default)
46
  except TypeError:
47
  return _orig_get(self, _make_hashable(key), default)
48
 
49
- _ju.LRUCache.__getitem__ = _safe_getitem
50
- _ju.LRUCache.__setitem__ = _safe_setitem
51
- _ju.LRUCache.get = _safe_get
52
 
53
  _patch_jinja2_lru_cache()
54
  del _patch_jinja2_lru_cache
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55
  # ─────────────────────────────────────────────────────────────────────────────
56
 
57
  # ── Compatibility patch ───────────────────────────────────────────────────────
 
4
  and exports the upgraded model to morpheuslord/rewrite on completion.
5
  """
6
 
7
+ # ── Patch 1: Jinja2 LRU cache ─────────────────────────────────────────────────
8
+ # Jinja2 >= 3.1.4 puts environment globals (a dict) into the LRU cache key,
9
+ # which is unhashable. Convert any unhashable element to a hashable equivalent.
 
 
 
 
 
 
 
10
  def _patch_jinja2_lru_cache():
11
  import jinja2.utils as _ju
12
 
 
14
  if isinstance(obj, dict):
15
  return frozenset((_make_hashable(k), _make_hashable(v)) for k, v in obj.items())
16
  if isinstance(obj, (list, tuple)):
17
+ return tuple(_make_hashable(i) for i in obj) # always tuple, never list
18
  return obj
19
 
20
+ _orig_gi = _ju.LRUCache.__getitem__
21
+ _orig_si = _ju.LRUCache.__setitem__
22
+ _orig_get = _ju.LRUCache.get
23
 
24
+ def _gi(self, key):
25
  try:
26
+ return _orig_gi(self, key)
27
  except TypeError:
28
+ return _orig_gi(self, _make_hashable(key))
29
 
30
+ def _si(self, key, value):
31
  try:
32
+ _orig_si(self, key, value)
33
  except TypeError:
34
+ _orig_si(self, _make_hashable(key), value)
35
 
36
+ def _get(self, key, default=None):
37
  try:
38
  return _orig_get(self, key, default)
39
  except TypeError:
40
  return _orig_get(self, _make_hashable(key), default)
41
 
42
+ _ju.LRUCache.__getitem__ = _gi
43
+ _ju.LRUCache.__setitem__ = _si
44
+ _ju.LRUCache.get = _get
45
 
46
  _patch_jinja2_lru_cache()
47
  del _patch_jinja2_lru_cache
48
+
49
+ # ── Patch 2: Starlette TemplateResponse API change ────────────────────────────
50
+ # Gradio 4.44.0 calls: templates.TemplateResponse(name: str, context: dict)
51
+ # Newer Starlette (0.29+) changed the signature to:
52
+ # TemplateResponse(request, name: str, context: dict)
53
+ # so the context dict ends up as `name`, causing 'dict has no attribute split'.
54
+ # Detect the old calling convention by checking if args[0] is a string, and
55
+ # reorder arguments to match what newer Starlette expects.
56
+ def _patch_starlette_template_response():
57
+ import starlette.templating as _st
58
+
59
+ _orig = _st.Jinja2Templates.TemplateResponse
60
+
61
+ def _compat(self, *args, **kwargs):
62
+ # Old API: (name: str, context: dict, ...)
63
+ # New API: (request, name: str, context: dict, ...)
64
+ if args and isinstance(args[0], str):
65
+ name = args[0]
66
+ context = args[1] if len(args) > 1 else {}
67
+ request = context.get("request")
68
+ return _orig(self, request, name, context, *args[2:], **kwargs)
69
+ return _orig(self, *args, **kwargs)
70
+
71
+ _st.Jinja2Templates.TemplateResponse = _compat
72
+
73
+ _patch_starlette_template_response()
74
+ del _patch_starlette_template_response
75
  # ─────────────────────────────────────────────────────────────────────────────
76
 
77
  # ── Compatibility patch ───────────────────────────────────────────────────────