test1978 commited on
Commit
3dd414c
Β·
verified Β·
1 Parent(s): 119aeb8

Add handler.py

Browse files
Files changed (1) hide show
  1. handler.py +56 -72
handler.py CHANGED
@@ -1,7 +1,10 @@
1
  # ──────────────────────────────────────────────
2
- # handler.py
3
  #
4
- # Custom handler for HF Inference Endpoints.
 
 
 
5
  #
6
  # When HF Inference Endpoints detects a handler.py
7
  # in the repo root, it uses this class to serve
@@ -11,28 +14,27 @@
11
  # Expected repo layout:
12
  #
13
  # your-username/breakthrough-model/
14
- # β”œβ”€β”€ handler.py ← this file
15
- # β”œβ”€β”€ config_model.json ← lists your Python modules + main
16
- # β”œβ”€β”€ config_data.json ← lists data files + zone_db key
17
  # β”œβ”€β”€ breakthrough_mcvs.py ← your UCT search / eval module
18
  # └── requirements.txt ← runtime deps (numpy, huggingface_hub)
19
  #
20
- # config_model.json example:
21
  #
22
- # {
23
- # "files": ["matrix_model.py", "abc_model.py", "breakthrough_mcvs.py"],
24
- # "main": "breakthrough_mcvs"
25
- # }
26
  #
27
- # config_data.json example:
28
  #
29
  # {
30
- # "files": ["breakthrough_zone_db.npz"],
31
- # "zone_db": "breakthrough_zone_db.npz"
 
32
  # }
33
  #
34
- # Set the HF_DATA_REPO_ID environment variable to
35
- # the HF dataset repo holding your data files.
 
36
  #
37
  # Request format (sent by Agladiator):
38
  #
@@ -89,9 +91,9 @@ class EndpointHandler:
89
  """Load model artefacts from *path* (the cloned repo directory).
90
 
91
  Steps:
92
- 1. Read ``config_model.json`` to discover module files and main module.
93
  2. Dynamically import each listed module.
94
- 3. Read ``config_data.json``, download data files, load zone DB.
95
  4. Initialise the search engine.
96
  """
97
  self.path = Path(path)
@@ -99,23 +101,21 @@ class EndpointHandler:
99
  self.zone_db = None
100
  self.module = None
101
 
102
- # ── 1. Read config_model.json ───────────
103
- model_config_path = self.path / "config_model.json"
104
- if not model_config_path.exists():
105
  log.warning("No config_model.json found in %s", path)
106
- model_config: dict = {}
107
  else:
108
- with open(model_config_path) as fh:
109
- model_config = json.load(fh)
110
-
111
- main_module_name = model_config.get("main", "")
112
 
113
  # ── 2. Import listed modules ────────────
114
  # Add repo dir to sys.path so relative imports work.
115
  if str(self.path) not in sys.path:
116
  sys.path.insert(0, str(self.path))
117
 
118
- for mod_file in model_config.get("files", []):
119
  mod_name = mod_file.removesuffix(".py")
120
  mod_path = self.path / mod_file
121
  if not mod_path.exists():
@@ -125,66 +125,50 @@ class EndpointHandler:
125
  mod = importlib.util.module_from_spec(spec)
126
  sys.modules[mod_name] = mod
127
  spec.loader.exec_module(mod)
 
 
128
  log.info("Loaded module: %s", mod_name)
129
- # Mark the module matching "main" as the primary module.
130
- if mod_name == main_module_name:
131
- self.module = mod
132
-
133
- # ── 3. Read config_data.json & load zone DB ──
134
- data_config_path = self.path / "config_data.json"
135
- if not data_config_path.exists():
136
- log.warning("No config_data.json found in %s", path)
137
- data_config: dict = {}
138
- else:
139
- with open(data_config_path) as fh:
140
- data_config = json.load(fh)
141
 
142
- data_repo = os.environ.get("HF_DATA_REPO_ID", "")
143
- downloaded_files: dict[str, str] = {}
 
 
 
 
 
 
144
 
145
  if data_repo:
 
146
  try:
147
  from huggingface_hub import hf_hub_download
 
 
 
 
 
 
 
 
148
  except Exception:
149
- hf_hub_download = None
150
- log.warning(
151
- "huggingface_hub not installed β€” cannot download data files. Add it to requirements.txt"
 
152
  )
153
 
154
- if hf_hub_download is not None:
155
- for data_file in data_config.get("files", []):
156
- try:
157
- local_path = hf_hub_download(
158
- repo_id=data_repo,
159
- filename=data_file,
160
- repo_type="dataset",
161
- )
162
- downloaded_files[data_file] = local_path
163
- log.info("Downloaded %s from %s", data_file, data_repo)
164
- except Exception:
165
- log.warning(
166
- "Failed to download %s from %s β€” skipping.",
167
- data_file,
168
- data_repo,
169
- )
170
- else:
171
- log.warning(
172
- "HF_DATA_REPO_ID not set β€” skipping data file downloads."
173
- )
174
-
175
- zone_db_filename = data_config.get("zone_db", "")
176
- if zone_db_filename and zone_db_filename in downloaded_files:
177
- self.zone_db = np.load(
178
- downloaded_files[zone_db_filename], allow_pickle=True
179
- )
180
- log.info("Zone DB loaded from data repo %s", data_repo)
181
- elif zone_db_filename:
182
  local_zone = self.path / zone_db_filename
183
  if local_zone.exists():
184
  self.zone_db = np.load(str(local_zone), allow_pickle=True)
185
  log.info("Zone DB loaded from local file %s", local_zone)
186
  else:
187
- log.warning("No zone DB found for '%s'.", zone_db_filename)
 
 
 
 
188
 
189
  # ── 4. Initialise the predictor ─────────
190
  self._init_predictor()
 
1
  # ──────────────────────────────────────────────
2
+ # sample_breakthrough_handler.py
3
  #
4
+ # Sample custom handler for HF Inference Endpoints.
5
+ #
6
+ # *** COPY THIS FILE INTO YOUR BREAKTHROUGH HF
7
+ # MODEL REPO AS ``handler.py``. ***
8
  #
9
  # When HF Inference Endpoints detects a handler.py
10
  # in the repo root, it uses this class to serve
 
14
  # Expected repo layout:
15
  #
16
  # your-username/breakthrough-model/
17
+ # β”œβ”€β”€ handler.py ← this file (rename to handler.py)
18
+ # β”œβ”€β”€ config_model.json ← lists your Python modules
 
19
  # β”œβ”€β”€ breakthrough_mcvs.py ← your UCT search / eval module
20
  # └── requirements.txt ← runtime deps (numpy, huggingface_hub)
21
  #
22
+ # And if you have a separate data repo for the zone DB:
23
  #
24
+ # your-username/breakthrough-data/
25
+ # └── zone_db.npz
 
 
26
  #
27
+ # config_model.json example:
28
  #
29
  # {
30
+ # "modules": ["breakthrough_mcvs.py"],
31
+ # "data_repo_id": "your-username/breakthrough-data",
32
+ # "zone_db_filename": "zone_db.npz"
33
  # }
34
  #
35
+ # If the zone DB lives in your model repo instead
36
+ # of a separate data repo, omit "data_repo_id" and
37
+ # place zone_db.npz alongside handler.py.
38
  #
39
  # Request format (sent by Agladiator):
40
  #
 
91
  """Load model artefacts from *path* (the cloned repo directory).
92
 
93
  Steps:
94
+ 1. Read ``config_model.json`` to discover module files.
95
  2. Dynamically import each listed module.
96
+ 3. Download / load the zone database.
97
  4. Initialise the search engine.
98
  """
99
  self.path = Path(path)
 
101
  self.zone_db = None
102
  self.module = None
103
 
104
+ # ── 1. Read config ──────────────────────
105
+ config_path = self.path / "config_model.json"
106
+ if not config_path.exists():
107
  log.warning("No config_model.json found in %s", path)
108
+ self.config: dict = {}
109
  else:
110
+ with open(config_path) as fh:
111
+ self.config = json.load(fh)
 
 
112
 
113
  # ── 2. Import listed modules ────────────
114
  # Add repo dir to sys.path so relative imports work.
115
  if str(self.path) not in sys.path:
116
  sys.path.insert(0, str(self.path))
117
 
118
+ for mod_file in self.config.get("modules", []):
119
  mod_name = mod_file.removesuffix(".py")
120
  mod_path = self.path / mod_file
121
  if not mod_path.exists():
 
125
  mod = importlib.util.module_from_spec(spec)
126
  sys.modules[mod_name] = mod
127
  spec.loader.exec_module(mod)
128
+ # Keep the last loaded module as the "main" module.
129
+ self.module = mod
130
  log.info("Loaded module: %s", mod_name)
 
 
 
 
 
 
 
 
 
 
 
 
131
 
132
+ # ── 3. Load zone database ───────────────
133
+ zone_db_filename = self.config.get("zone_db_filename", "zone_db.npz")
134
+
135
+ # Check env var first (set by Agladiator platform), then config.
136
+ data_repo = os.environ.get(
137
+ "HF_DATA_REPO_ID",
138
+ self.config.get("data_repo_id", ""),
139
+ )
140
 
141
  if data_repo:
142
+ # Download from the linked HF dataset repo.
143
  try:
144
  from huggingface_hub import hf_hub_download
145
+
146
+ zone_path = hf_hub_download(
147
+ repo_id=data_repo,
148
+ filename=zone_db_filename,
149
+ repo_type="dataset",
150
+ )
151
+ self.zone_db = np.load(zone_path, allow_pickle=True)
152
+ log.info("Zone DB loaded from data repo %s", data_repo)
153
  except Exception:
154
+ log.exception(
155
+ "Failed to download zone DB from %s β€” "
156
+ "falling back to local file.",
157
+ data_repo,
158
  )
159
 
160
+ # Fall back to a local copy in the model repo.
161
+ if self.zone_db is None:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  local_zone = self.path / zone_db_filename
163
  if local_zone.exists():
164
  self.zone_db = np.load(str(local_zone), allow_pickle=True)
165
  log.info("Zone DB loaded from local file %s", local_zone)
166
  else:
167
+ log.warning(
168
+ "No zone DB found (checked data repo '%s' and local '%s').",
169
+ data_repo,
170
+ local_zone,
171
+ )
172
 
173
  # ── 4. Initialise the predictor ─────────
174
  self._init_predictor()