yicloud-sdk-python 0.1.0__py3-none-any.whl

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.
Files changed (59) hide show
  1. version.py +9 -0
  2. yicloud/__init__.py +7 -0
  3. yicloud/base/__init__.py +58 -0
  4. yicloud/base/auth/__init__.py +10 -0
  5. yicloud/base/auth/credential.py +64 -0
  6. yicloud/base/auth/sign.py +80 -0
  7. yicloud/base/client.py +313 -0
  8. yicloud/base/config.py +62 -0
  9. yicloud/base/errs/__init__.py +292 -0
  10. yicloud/base/log/__init__.py +43 -0
  11. yicloud/base/log/logger.py +123 -0
  12. yicloud/base/log/std.py +70 -0
  13. yicloud/base/msgs/__init__.py +226 -0
  14. yicloud/base/utils/__init__.py +6 -0
  15. yicloud/base/utils/helps.py +110 -0
  16. yicloud/base/utils/retry/__init__.py +27 -0
  17. yicloud/base/utils/retry/retry.py +162 -0
  18. yicloud/services/__init__.py +24 -0
  19. yicloud/services/bc/__init__.py +9 -0
  20. yicloud/services/bc/actions.py +23 -0
  21. yicloud/services/bc/client.py +19 -0
  22. yicloud/services/bc/models.py +61 -0
  23. yicloud/services/fs/__init__.py +29 -0
  24. yicloud/services/fs/actions.py +109 -0
  25. yicloud/services/fs/client.py +19 -0
  26. yicloud/services/fs/models.py +152 -0
  27. yicloud/services/iam/__init__.py +27 -0
  28. yicloud/services/iam/actions.py +304 -0
  29. yicloud/services/iam/client.py +19 -0
  30. yicloud/services/iam/models.py +276 -0
  31. yicloud/services/job/__init__.py +44 -0
  32. yicloud/services/job/actions.py +167 -0
  33. yicloud/services/job/client.py +19 -0
  34. yicloud/services/job/models.py +268 -0
  35. yicloud/services/mc/__init__.py +59 -0
  36. yicloud/services/mc/actions.py +221 -0
  37. yicloud/services/mc/client.py +21 -0
  38. yicloud/services/mc/models.py +322 -0
  39. yicloud/services/modelrepo/__init__.py +33 -0
  40. yicloud/services/modelrepo/actions.py +163 -0
  41. yicloud/services/modelrepo/client.py +19 -0
  42. yicloud/services/modelrepo/models.py +146 -0
  43. yicloud/services/modelset/__init__.py +45 -0
  44. yicloud/services/modelset/actions.py +130 -0
  45. yicloud/services/modelset/client.py +19 -0
  46. yicloud/services/modelset/models.py +356 -0
  47. yicloud/services/oss/__init__.py +25 -0
  48. yicloud/services/oss/actions.py +83 -0
  49. yicloud/services/oss/client.py +19 -0
  50. yicloud/services/oss/models.py +113 -0
  51. yicloud/services/registry/__init__.py +42 -0
  52. yicloud/services/registry/actions.py +208 -0
  53. yicloud/services/registry/client.py +19 -0
  54. yicloud/services/registry/models.py +183 -0
  55. yicloud_sdk_python-0.1.0.dist-info/METADATA +145 -0
  56. yicloud_sdk_python-0.1.0.dist-info/RECORD +59 -0
  57. yicloud_sdk_python-0.1.0.dist-info/WHEEL +5 -0
  58. yicloud_sdk_python-0.1.0.dist-info/licenses/LICENSE +202 -0
  59. yicloud_sdk_python-0.1.0.dist-info/top_level.txt +2 -0
@@ -0,0 +1,292 @@
1
+ from typing import Protocol, Any, Optional
2
+ import requests
3
+
4
+
5
+ ErrHTTPStatus = "server.HTTPStatusError"
6
+ ErrRetCode = "server.RetCodeError"
7
+
8
+
9
+ class Error(Protocol):
10
+ """Base error interface matching Go's Error interface."""
11
+
12
+ def __str__(self) -> str: ...
13
+
14
+ @property
15
+ def action(self) -> str: ...
16
+
17
+ @property
18
+ def code(self) -> int: ...
19
+
20
+ @property
21
+ def message(self) -> str: ...
22
+
23
+ @property
24
+ def status_code(self) -> int: ...
25
+
26
+
27
+ # YiCloudException - base exception for all SDK errors
28
+ class YiCloudException(Exception):
29
+ """Base exception for all YiCloud SDK errors.
30
+
31
+ Users can catch this exception type to handle all SDK errors:
32
+
33
+ try:
34
+ client.do_something()
35
+ except exc.YiCloudException as e:
36
+ print(f"YiCloud error: {e}")
37
+ """
38
+
39
+ def __str__(self) -> str:
40
+ return f"YiCloudException: {self}"
41
+
42
+ @property
43
+ def action(self) -> str:
44
+ return ""
45
+
46
+ @property
47
+ def code(self) -> int:
48
+ return 0
49
+
50
+ @property
51
+ def message(self) -> str:
52
+ return str(self) if self else "yicloud error"
53
+
54
+ @property
55
+ def status_code(self) -> int:
56
+ return 0
57
+
58
+
59
+ # ClientException - client-side errors (SDK side issues)
60
+ class ClientException(Error, YiCloudException):
61
+ """
62
+ Client-side errors (invalid params, signing, network).
63
+
64
+ This is SDK-side errors that occur before or during the request.
65
+ """
66
+
67
+ def __init__(self, action: str, err: Optional[Exception] = None):
68
+ self._action = action
69
+ self._err = err
70
+
71
+ def __str__(self) -> str:
72
+ return f"ClientException[action={self._action}]: {self._err}"
73
+
74
+ def __repr__(self) -> str:
75
+ return f"<ClientException action={self._action} err={self._err}>"
76
+
77
+ @property
78
+ def action(self) -> str:
79
+ return self._action
80
+
81
+ @property
82
+ def code(self) -> int:
83
+ return -1
84
+
85
+ @property
86
+ def status_code(self) -> int:
87
+ return 0
88
+
89
+ @property
90
+ def message(self) -> str:
91
+ return str(self._err) if self._err else "client error"
92
+
93
+ @property
94
+ def err(self) -> Optional[Exception]:
95
+ return self._err
96
+
97
+
98
+ # ServerException - server-side errors (API response issues)
99
+ class ServerException(Error, YiCloudException):
100
+ """
101
+ Server-side errors (HTTP status, business return code).
102
+
103
+ This is API response errors returned from the server.
104
+ """
105
+
106
+ def __init__(
107
+ self,
108
+ action: str,
109
+ status_code: int = 0,
110
+ ret_code: int = 0,
111
+ message: str = "",
112
+ request_id: str = ""
113
+ ):
114
+ self._action = action
115
+ self._status_code = status_code
116
+ self._ret_code = ret_code
117
+ self._message = message if message else "server error"
118
+ self._request_id = request_id
119
+
120
+ def __str__(self) -> str:
121
+ return (f"ServerException[action={self._action}, status_code={self._status_code}, "
122
+ f"ret_code={self._ret_code}, request_id={self._request_id}]: {self._message}")
123
+
124
+ def __repr__(self) -> str:
125
+ return (f"<ServerException action={self._action} status_code={self._status_code} "
126
+ f"ret_code={self._ret_code} request_id={self._request_id}>")
127
+
128
+ @property
129
+ def action(self) -> str:
130
+ return self._action
131
+
132
+ @property
133
+ def code(self) -> int:
134
+ return self._ret_code
135
+
136
+ @property
137
+ def status_code(self) -> int:
138
+ return self._status_code
139
+
140
+ @property
141
+ def message(self) -> str:
142
+ return self._message
143
+
144
+ @property
145
+ def request_id(self) -> str:
146
+ return self._request_id
147
+
148
+
149
+ # Helper functions for type checking
150
+ def is_client_error(err: Any) -> bool:
151
+ """
152
+ Check if error is a ClientException.
153
+
154
+ Can be used with Error objects or exceptions.
155
+ """
156
+ return isinstance(err, ClientException)
157
+
158
+
159
+ def as_client_error(err: Any) -> Optional[ClientException]:
160
+ """
161
+ Return error as ClientException if it is one, otherwise None.
162
+
163
+ This is a type guard that can be used in if statements.
164
+ """
165
+ if is_client_error(err):
166
+ return err
167
+ return None
168
+
169
+
170
+ def is_server_error(err: Any) -> bool:
171
+ """
172
+ Check if error is a ServerException.
173
+
174
+ Can be used with Error objects or exceptions.
175
+ """
176
+ return isinstance(err, ServerException)
177
+
178
+
179
+ def as_server_error(err: Any) -> Optional[ServerException]:
180
+ """
181
+ Return error as ServerException if it is one, otherwise None.
182
+
183
+ This is a type guard that can be used in if statements.
184
+ """
185
+ if is_server_error(err):
186
+ return err
187
+ return None
188
+
189
+
190
+ def is_network_error(err: Any) -> bool:
191
+ """
192
+ Check if the error is from network problem.
193
+
194
+ Returns True if the error is a network-related error that might be retryable.
195
+ """
196
+ if err is None:
197
+ return False
198
+
199
+ # Check for requests.RequestException (base class for all requests exceptions)
200
+ if isinstance(err, requests.RequestException):
201
+ return True
202
+
203
+ # Check for common network-related error patterns
204
+ err_str = str(err).lower()
205
+ network_patterns = [
206
+ "connection error",
207
+ "connect timeout",
208
+ "read timeout",
209
+ "connection refused",
210
+ "connection reset",
211
+ "network unreachable",
212
+ "host unreachable",
213
+ "hostname mismatch",
214
+ "certificate verify failed",
215
+ "certificate verify",
216
+ "ssl",
217
+ "tls",
218
+ "request canceled",
219
+ ]
220
+
221
+ for pattern in network_patterns:
222
+ if pattern in err_str:
223
+ return True
224
+
225
+ # Check for requests specific exception types
226
+ err_type = type(err).__name__
227
+ network_types = [
228
+ "ConnectionError",
229
+ "Timeout",
230
+ "HTTPError",
231
+ "SSLError",
232
+ "ProxyError",
233
+ "ChunkedEncodingError",
234
+ "ContentDecodingError",
235
+ "TooManyRedirects",
236
+ ]
237
+
238
+ for net_type in network_types:
239
+ if net_type in err_type:
240
+ return True
241
+
242
+ return False
243
+
244
+
245
+ def is_code_error(err: Any) -> bool:
246
+ """
247
+ Check if error has non-zero business return code.
248
+
249
+ Returns True if the error is a ServerException with non-zero ret_code.
250
+ """
251
+ if err is None:
252
+ return False
253
+ return isinstance(err, ServerException) and err.code != 0
254
+
255
+
256
+ # Factory functions for creating errors
257
+ def new_client_error(action: str, err: Optional[Exception] = None) -> ClientException:
258
+ """Create a new ClientException."""
259
+ return ClientException(action, err)
260
+
261
+
262
+ def new_server_error(
263
+ action: str,
264
+ status_code: int = 0,
265
+ ret_code: int = 0,
266
+ message: str = "",
267
+ request_id: str = ""
268
+ ) -> ServerException:
269
+ """Create a new ServerException."""
270
+ return ServerException(action, status_code, ret_code, message, request_id)
271
+
272
+
273
+ __all__ = [
274
+ # Exception types
275
+ "YiCloudException",
276
+ "ClientException",
277
+ "ServerException",
278
+ "Error",
279
+ # Factory functions
280
+ "new_client_error",
281
+ "new_server_error",
282
+ # Type checking functions
283
+ "is_client_error",
284
+ "as_client_error",
285
+ "is_server_error",
286
+ "as_server_error",
287
+ "is_network_error",
288
+ "is_code_error",
289
+ # Error constants
290
+ "ErrHTTPStatus",
291
+ "ErrRetCode",
292
+ ]
@@ -0,0 +1,43 @@
1
+ from yicloud.base.log.logger import (
2
+ Logger,
3
+ Level,
4
+ new,
5
+ new_with_writer,
6
+ get_default_logger,
7
+ debug,
8
+ debugf,
9
+ info,
10
+ infof,
11
+ warn,
12
+ warnf,
13
+ error,
14
+ errorf,
15
+ set_output,
16
+ set_writer,
17
+ set_level,
18
+ get_level,
19
+ )
20
+ from yicloud.base.log.std import StdLogger, new_std_logger, new_std_logger_with_writer
21
+
22
+ __all__ = [
23
+ "Logger",
24
+ "Level",
25
+ "StdLogger",
26
+ "new",
27
+ "new_with_writer",
28
+ "new_std_logger",
29
+ "new_std_logger_with_writer",
30
+ "get_default_logger",
31
+ "debug",
32
+ "debugf",
33
+ "info",
34
+ "infof",
35
+ "warn",
36
+ "warnf",
37
+ "error",
38
+ "errorf",
39
+ "set_output",
40
+ "set_writer",
41
+ "set_level",
42
+ "get_level",
43
+ ]
@@ -0,0 +1,123 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Any, Protocol, runtime_checkable, TextIO
3
+
4
+
5
+ class Level:
6
+ """Log level constants matching Go SDK."""
7
+ DEBUG = 0
8
+ INFO = 1
9
+ WARN = 2
10
+ ERROR = 3
11
+
12
+ @classmethod
13
+ def string(cls, level: int) -> str:
14
+ if level == cls.DEBUG:
15
+ return "debug"
16
+ elif level == cls.INFO:
17
+ return "info"
18
+ elif level == cls.WARN:
19
+ return "warn"
20
+ elif level == cls.ERROR:
21
+ return "error"
22
+ return "unknown"
23
+
24
+
25
+ @runtime_checkable
26
+ class Logger(Protocol):
27
+ """Logger interface matching Go SDK's Logger."""
28
+
29
+ def debug(self, *args: Any): ...
30
+
31
+ def debugf(self, format: str, *args: Any): ...
32
+
33
+ def info(self, *args: Any): ...
34
+
35
+ def infof(self, format: str, *args: Any): ...
36
+
37
+ def warn(self, *args: Any): ...
38
+
39
+ def warnf(self, format: str, *args: Any): ...
40
+
41
+ def error(self, *args: Any): ...
42
+
43
+ def errorf(self, format: str, *args: Any): ...
44
+
45
+ def set_output(self, output: TextIO): ...
46
+
47
+ def set_level(self, level: int): ...
48
+
49
+ def get_level(self) -> int: ...
50
+
51
+
52
+ def new() -> Logger:
53
+ return new_with_writer(None)
54
+
55
+
56
+ def new_with_writer(output: TextIO) -> Logger:
57
+ from .std import new_std_logger_with_writer
58
+ return new_std_logger_with_writer(output)
59
+
60
+
61
+ defaultLogger: Logger = None
62
+
63
+
64
+ def _init():
65
+ global defaultLogger
66
+ defaultLogger = new()
67
+
68
+
69
+ _init()
70
+
71
+
72
+ def get_default_logger() -> Logger:
73
+ return defaultLogger
74
+
75
+
76
+ def debug(*args: Any):
77
+ defaultLogger.debug(*args)
78
+
79
+
80
+ def debugf(format: str, *args: Any):
81
+ defaultLogger.debugf(format, *args)
82
+
83
+
84
+ def info(*args: Any):
85
+ defaultLogger.info(*args)
86
+
87
+
88
+ def infof(format: str, *args: Any):
89
+ defaultLogger.infof(format, *args)
90
+
91
+
92
+ def warn(*args: Any):
93
+ defaultLogger.warn(*args)
94
+
95
+
96
+ def warnf(format: str, *args: Any):
97
+ defaultLogger.warnf(format, *args)
98
+
99
+
100
+ def error(*args: Any):
101
+ defaultLogger.error(*args)
102
+
103
+
104
+ def errorf(format: str, *args: Any):
105
+ defaultLogger.errorf(format, *args)
106
+
107
+
108
+ def set_output(output: TextIO):
109
+ defaultLogger.set_output(output)
110
+
111
+
112
+ def set_writer(output: TextIO):
113
+ """Set default output writer for third-party logger integration."""
114
+ global defaultLogger
115
+ defaultLogger = new_with_writer(output)
116
+
117
+
118
+ def set_level(level: int):
119
+ defaultLogger.set_level(level)
120
+
121
+
122
+ def get_level() -> int:
123
+ return defaultLogger.get_level()
@@ -0,0 +1,70 @@
1
+ import sys
2
+ import datetime
3
+ from typing import Any, TextIO
4
+ from yicloud.base.log.logger import Logger, Level
5
+
6
+
7
+ class StdLogger(Logger):
8
+ """Std logger using standard library output, matching Go SDK's stdLogger."""
9
+
10
+ def __init__(self, output: TextIO = None):
11
+ self.level = Level.WARN
12
+ self.output = output if output else sys.stdout
13
+
14
+ def _is_enabled(self, level: int) -> bool:
15
+ return level >= self.level
16
+
17
+ def _log(self, level: int, *args: Any):
18
+ if not self._is_enabled(level):
19
+ return
20
+ msg = " ".join(str(arg) for arg in args)
21
+ timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
22
+ print(f"[{timestamp}] [{Level.string(level)}] {msg}", file=self.output)
23
+
24
+ def _logf(self, level: int, format: str, *args: Any):
25
+ if not self._is_enabled(level):
26
+ return
27
+ timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S")
28
+ msg = format % args if args else format
29
+ print(f"[{timestamp}] [{Level.string(level)}] {msg}", file=self.output)
30
+
31
+ def debug(self, *args: Any):
32
+ self._log(Level.DEBUG, *args)
33
+
34
+ def debugf(self, format: str, *args: Any):
35
+ self._logf(Level.DEBUG, format, *args)
36
+
37
+ def info(self, *args: Any):
38
+ self._log(Level.INFO, *args)
39
+
40
+ def infof(self, format: str, *args: Any):
41
+ self._logf(Level.INFO, format, *args)
42
+
43
+ def warn(self, *args: Any):
44
+ self._log(Level.WARN, *args)
45
+
46
+ def warnf(self, format: str, *args: Any):
47
+ self._logf(Level.WARN, format, *args)
48
+
49
+ def error(self, *args: Any):
50
+ self._log(Level.ERROR, *args)
51
+
52
+ def errorf(self, format: str, *args: Any):
53
+ self._logf(Level.ERROR, format, *args)
54
+
55
+ def set_output(self, output: TextIO):
56
+ self.output = output
57
+
58
+ def set_level(self, level: int):
59
+ self.level = level
60
+
61
+ def get_level(self) -> int:
62
+ return self.level
63
+
64
+
65
+ def new_std_logger() -> StdLogger:
66
+ return new_std_logger_with_writer(None)
67
+
68
+
69
+ def new_std_logger_with_writer(output: TextIO) -> StdLogger:
70
+ return StdLogger(output)