IDS75912 commited on
Commit
059d1d9
·
1 Parent(s): 521c944
Files changed (1) hide show
  1. main.py +59 -23
main.py CHANGED
@@ -13,20 +13,18 @@ from typing import Any, Dict
13
  import os
14
  import pkgutil
15
 
16
-
17
  from huggingface_hub import hf_hub_download
 
 
 
 
18
  from typing import Any, Dict
19
 
20
  import tensorflow as tf
21
-
22
-
23
-
24
  from tensorflow import keras
25
 
26
-
27
-
28
-
29
-
30
  app = FastAPI(title="1.3 - AI Model Deployment")
31
  ''' browser: http://localhost:8000/docs'''
32
 
@@ -40,10 +38,6 @@ app.add_middleware(
40
  )
41
 
42
 
43
-
44
-
45
-
46
-
47
  ANIMALS = ['Cat', 'Dog', 'Panda'] # Animal names here, these represent the labels of the images that we trained our model on.
48
 
49
  # 1) download your SavedModel from the Hub into a writable directory (Spaces often
@@ -57,24 +51,64 @@ try:
57
  except PermissionError:
58
  raise RuntimeError(f"Cannot create model directory '{local_model_dir}'. Ensure the process has write access or set HF_MODEL_DIR to a writable path.")
59
 
60
- # download files into local_model_dir
61
- hf_hub_download(repo_id, filename="config.json", repo_type="model", local_dir=local_model_dir)
62
- hf_hub_download(repo_id, filename="metadata.json", repo_type="model", local_dir=local_model_dir)
63
- hf_hub_download(repo_id, filename="model.weights.h5", repo_type="model", local_dir=local_model_dir)
64
-
65
- # 2) load it
66
- # If the hub returns an unpacked model folder, point load_model at that directory.
67
  try:
68
- model = tf.keras.models.load_model(local_model_dir)
69
- except (IOError, OSError, ValueError) as e:
70
- raise RuntimeError(f"Failed to load model from '{local_model_dir}': {e}")
71
-
72
 
 
 
 
73
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
 
75
 
76
  @app.post('/upload/image')
77
  async def uploadImage(img: UploadFile = File(...)):
 
 
 
 
78
  original_image = Image.open(img.file) # Read the bytes and process as an image
79
  if original_image.mode == 'RGBA':
80
  original_image = original_image.convert('RGB')
@@ -111,6 +145,8 @@ def versions() -> Dict[str, Any]:
111
  def predict_stub() -> Dict[str, Any]:
112
 
113
  # This is a stub, so we're not doing a real prediction
 
 
114
  return {"prediction": "stub, we're not doing a real prediction"}
115
 
116
 
 
13
  import os
14
  import pkgutil
15
 
 
16
  from huggingface_hub import hf_hub_download
17
+ from huggingface_hub import hf_hub_url
18
+ import requests
19
+ import tempfile
20
+ import shutil
21
  from typing import Any, Dict
22
 
23
  import tensorflow as tf
24
+ import traceback
25
+ import logging
 
26
  from tensorflow import keras
27
 
 
 
 
 
28
  app = FastAPI(title="1.3 - AI Model Deployment")
29
  ''' browser: http://localhost:8000/docs'''
30
 
 
38
  )
39
 
40
 
 
 
 
 
41
  ANIMALS = ['Cat', 'Dog', 'Panda'] # Animal names here, these represent the labels of the images that we trained our model on.
42
 
43
  # 1) download your SavedModel from the Hub into a writable directory (Spaces often
 
51
  except PermissionError:
52
  raise RuntimeError(f"Cannot create model directory '{local_model_dir}'. Ensure the process has write access or set HF_MODEL_DIR to a writable path.")
53
 
54
+ # download files into local_model_dir and load model with resilient error handling
55
+ model = None
56
+ model_load_error = None
 
 
 
 
57
  try:
58
+ # First try using a cache dir so downloads happen in a shared cache and final move
59
+ # into local_model_dir is less likely to require risky renames inside the repo.
60
+ cache_dir = '/tmp/.cache/huggingface'
61
+ os.makedirs(cache_dir, exist_ok=True)
62
 
63
+ hf_hub_download(repo_id, filename="config.json", repo_type="model", local_dir=local_model_dir, cache_dir=cache_dir)
64
+ hf_hub_download(repo_id, filename="metadata.json", repo_type="model", local_dir=local_model_dir, cache_dir=cache_dir)
65
+ hf_hub_download(repo_id, filename="model.weights.h5", repo_type="model", local_dir=local_model_dir, cache_dir=cache_dir)
66
 
67
+ # 2) load it
68
+ model = tf.keras.models.load_model(local_model_dir)
69
+ logging.info(f"Model loaded successfully from {local_model_dir}")
70
+ except Exception as e:
71
+ # Primary download attempt failed -> try streamed fallback which writes directly
72
+ # into local_model_dir (avoids internal temp/move when those operations are blocked).
73
+ primary_err = e
74
+ logging.error("Primary hf_hub_download failed, attempting streamed fallback: %s", e)
75
+ try:
76
+ for filename in ("config.json", "metadata.json", "model.weights.h5"):
77
+ url = hf_hub_url(repo_id=repo_id, filename=filename, repo_type='model')
78
+ logging.info(f"Streaming {filename} from {url} into {local_model_dir}")
79
+ resp = requests.get(url, stream=True, timeout=60)
80
+ resp.raise_for_status()
81
+ # write to a temp file inside the target dir then move atomically
82
+ with tempfile.NamedTemporaryFile(dir=local_model_dir, delete=False) as tmpf:
83
+ for chunk in resp.iter_content(chunk_size=8192):
84
+ if chunk:
85
+ tmpf.write(chunk)
86
+ tmp_path = tmpf.name
87
+ final_path = os.path.join(local_model_dir, filename)
88
+ try:
89
+ shutil.move(tmp_path, final_path)
90
+ except Exception:
91
+ # if atomic move fails, try copy+remove
92
+ shutil.copy(tmp_path, final_path)
93
+ os.remove(tmp_path)
94
+
95
+ # After streamed download, try loading
96
+ model = tf.keras.models.load_model(local_model_dir)
97
+ logging.info(f"Model loaded successfully from {local_model_dir} after streamed fallback")
98
+ except Exception as e2:
99
+ model_load_error = f"primary: {primary_err}; fallback: {e2}"
100
+ tb = traceback.format_exc()
101
+ logging.error("Streamed fallback failed: %s", e2)
102
+ logging.error(tb)
103
+ model = None
104
 
105
 
106
  @app.post('/upload/image')
107
  async def uploadImage(img: UploadFile = File(...)):
108
+ if model is None:
109
+ # Model isn't available — return a helpful error to the caller instead of crashing.
110
+ return fastapi.Response(status_code=503, content=f"Model not loaded: {model_load_error}")
111
+
112
  original_image = Image.open(img.file) # Read the bytes and process as an image
113
  if original_image.mode == 'RGBA':
114
  original_image = original_image.convert('RGB')
 
145
  def predict_stub() -> Dict[str, Any]:
146
 
147
  # This is a stub, so we're not doing a real prediction
148
+ if model is None:
149
+ return {"prediction": "model not loaded", "error": model_load_error}
150
  return {"prediction": "stub, we're not doing a real prediction"}
151
 
152