aipmodel 0.2.75__tar.gz → 0.2.77__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aipmodel
3
- Version: 0.2.75
3
+ Version: 0.2.77
4
4
  Summary: SDK for model registration, versioning, and storage
5
5
  Home-page: https://github.com/AIP-MLOPS/model-registry
6
6
  Author: AIP MLOPS Team
@@ -37,6 +37,11 @@ _TRANSIENT_TRANSFER_ERRORS = tuple(
37
37
  "EndpointConnectionError",
38
38
  "ReadTimeoutError",
39
39
  "IncompleteReadError",
40
+ # boto3 wraps a mid-stream connection break (urllib3 ProtocolError /
41
+ # http IncompleteRead) into ResponseStreamingError before it reaches the
42
+ # caller, so the underlying transient types below never match on their
43
+ # own for a download that dies mid-body. Retry on the wrapper too.
44
+ "ResponseStreamingError",
40
45
  )
41
46
  if hasattr(_botocore_exceptions, _name)
42
47
  ) + (
@@ -628,8 +633,16 @@ class CephS3Manager:
628
633
  except _TRANSIENT_TRANSFER_ERRORS as e:
629
634
  attempt += 1
630
635
  if attempt > self.max_transfer_retries:
631
- if self.verbose:
632
- print(f"[SDK_FAIL] {label}: transient error persisted after {self.max_transfer_retries} retries: {e}")
636
+ # Always log this (not gated by verbose): a transient error that
637
+ # survives every retry is a NETWORK problem, and the user must be
638
+ # able to tell it apart from a Model Registry fault in the task log.
639
+ print(
640
+ f"[SDK_NETWORK_ERROR] {label}: NETWORK/connection failure — this is "
641
+ f"NOT a Model Registry problem. The connection to the storage endpoint "
642
+ f"kept dropping mid-transfer and did not recover after "
643
+ f"{self.max_transfer_retries} automatic retries. Check network "
644
+ f"stability and retry. Underlying: {type(e).__name__}: {e}"
645
+ )
633
646
  raise
634
647
  delay = min(self.transfer_retry_backoff * (2 ** (attempt - 1)), self.transfer_retry_max_delay)
635
648
  if self.verbose:
@@ -11,5 +11,5 @@ if _os.environ.get("AIPMODEL_UPDATE_CHECK", "").lower() in ("1", "true", "yes"):
11
11
 
12
12
  __all__ = ["MLOpsManager", "CephS3Manager"]
13
13
 
14
- __version__ = "0.2.75"
14
+ __version__ = "0.2.77"
15
15
  __description__ = "SDK for model registration, versioning, and storage"
@@ -20,6 +20,33 @@ from .CephS3Manager import CephS3Manager
20
20
  from .acl_manager import AclManager
21
21
  from .exceptions import ModelRegistryError, ModelNotFoundError, MetadataError, StorageError, IntegrityDisabledError
22
22
 
23
+
24
+ def _is_transient_network_error(exc):
25
+ """
26
+ True when a failure was caused by a transient NETWORK/connection problem
27
+ (dropped connection, mid-stream read break, timeout) rather than a Model
28
+ Registry / storage-content fault. Walks the exception chain and also matches
29
+ the wrapped message, because transfer errors bubble up re-wrapped as
30
+ ValueError ("S3 Transfer failed: ... Connection broken: IncompleteRead ...").
31
+ Used only to add a clear, human-readable "this is the network, not the
32
+ registry" note to the task log — it never changes control flow.
33
+ """
34
+ _NET_MARKERS = (
35
+ "connection broken", "incompleteread", "responsestreaming",
36
+ "connection reset", "connection aborted", "connection refused",
37
+ "connection was closed", "timed out", "read timeout", "broken pipe",
38
+ "network is unreachable", "eof occurred", "endpointconnection",
39
+ "connectionerror", "name or service not known", "temporary failure in name resolution",
40
+ )
41
+ seen = set()
42
+ e = exc
43
+ while e is not None and id(e) not in seen:
44
+ seen.add(id(e))
45
+ if any(m in str(e).lower() for m in _NET_MARKERS):
46
+ return True
47
+ e = getattr(e, "__cause__", None) or getattr(e, "__context__", None)
48
+ return False
49
+
23
50
  load_dotenv()
24
51
 
25
52
  logger = logging.getLogger(__name__)
@@ -1102,6 +1129,17 @@ class MLOpsManager:
1102
1129
  return model_id
1103
1130
 
1104
1131
  except (Exception, KeyboardInterrupt) as e:
1132
+ if _is_transient_network_error(e):
1133
+ print("[SDK_NETWORK_ERROR] ============================================================")
1134
+ print("[SDK_NETWORK_ERROR] Model add FAILED because of a NETWORK / connection problem")
1135
+ print("[SDK_NETWORK_ERROR] while transferring the model files.")
1136
+ print("[SDK_NETWORK_ERROR] This is NOT a Model Registry problem — the registry and the")
1137
+ print("[SDK_NETWORK_ERROR] storage are healthy. The connection to the storage/source")
1138
+ print("[SDK_NETWORK_ERROR] endpoint dropped and did not recover after the automatic")
1139
+ print("[SDK_NETWORK_ERROR] retries. Nothing was left half-written (rolled back).")
1140
+ print("[SDK_NETWORK_ERROR] Action: check network stability to the S3 source / Ceph,")
1141
+ print("[SDK_NETWORK_ERROR] then retry the add.")
1142
+ print("[SDK_NETWORK_ERROR] ============================================================")
1105
1143
  print(f"[SDK_ERROR] Add model failed: {e}")
1106
1144
  if "model_id" in locals():
1107
1145
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aipmodel
3
- Version: 0.2.75
3
+ Version: 0.2.77
4
4
  Summary: SDK for model registration, versioning, and storage
5
5
  Home-page: https://github.com/AIP-MLOPS/model-registry
6
6
  Author: AIP MLOPS Team
@@ -31,7 +31,7 @@ version, description = read_meta()
31
31
 
32
32
  setup(
33
33
  name="aipmodel",
34
- version="0.2.75",
34
+ version="0.2.77",
35
35
  description=description,
36
36
  author="AIP MLOPS Team",
37
37
  author_email="mohmmadweb@gmail.com",
File without changes
File without changes
File without changes
File without changes