kc-sdk-python 3.0.0__tar.gz → 4.0.0__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: kc-sdk-python
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: Kvindo Cloud Python SDK — typed client for managing Kvindo Cloud infrastructure (VMs, S3, Kubernetes, load balancers, VPCs, PostgreSQL) via the REST API
5
5
  Author: Kvindo
6
6
  License-Expression: MIT
@@ -45,6 +45,10 @@ balancers, VPCs, VPNs, and managed PostgreSQL.
45
45
  A thin, typed client over the REST API: one resource client per resource type, all sharing the
46
46
  same create / read / update / delete / list contract.
47
47
 
48
+ > **Using Claude Code?** This repo ships a [Claude Code skill](.claude/skills/kvindo-python-sdk/SKILL.md)
49
+ > that teaches Claude how to script Kvindo Cloud with this SDK — clone this repo (or otherwise have
50
+ > it on disk) and open Claude Code there to pick it up automatically.
51
+
48
52
  ## Install
49
53
 
50
54
  ```sh
@@ -59,6 +63,9 @@ Dependencies: `requests`, `marshmallow-dataclass`, `py-ulid`.
59
63
  from kc_api import KcClient
60
64
 
61
65
  client = KcClient("YOUR_API_TOKEN") # api_url defaults to https://cloud-api.kvindo.ru
66
+ # TLS certificate verification is on by default (verify_ssl=True). Pass
67
+ # verify_ssl=False only to point this SDK at a genuinely self-hosted instance
68
+ # with a self-signed cert.
62
69
 
63
70
  # List (label-filtered, paginated)
64
71
  resp = client.vms.get_by_labels({"env": "prod"}, max_page_size=50)
@@ -100,7 +107,9 @@ Part of the Kvindo Cloud developer toolchain:
100
107
 
101
108
  - **[kc CLI](https://github.com/Kvindo/kc-cli)** — kubectl-style command-line client for Kvindo Cloud.
102
109
  - **[terraform-provider-kvindo](https://github.com/Kvindo/terraform-provider-kvindo)** — Terraform provider ([Registry](https://registry.terraform.io/providers/kvindo/kvindo/latest)).
110
+ - **[kc-mcp-server](https://github.com/Kvindo/kc-mcp-server)** — MCP server for Kvindo Cloud ([npm](https://www.npmjs.com/package/kc-mcp-server)), for managing resources from Claude Desktop/Code and other MCP clients.
103
111
  - **[Kvindo Cloud console](https://cloud.kvindo.com)** — web UI and API.
112
+ - **[Claude Code skill](.claude/skills/kvindo-python-sdk/SKILL.md)** — lets Claude script Kvindo Cloud with this SDK conversationally.
104
113
 
105
114
  ## License
106
115
 
@@ -11,6 +11,10 @@ balancers, VPCs, VPNs, and managed PostgreSQL.
11
11
  A thin, typed client over the REST API: one resource client per resource type, all sharing the
12
12
  same create / read / update / delete / list contract.
13
13
 
14
+ > **Using Claude Code?** This repo ships a [Claude Code skill](.claude/skills/kvindo-python-sdk/SKILL.md)
15
+ > that teaches Claude how to script Kvindo Cloud with this SDK — clone this repo (or otherwise have
16
+ > it on disk) and open Claude Code there to pick it up automatically.
17
+
14
18
  ## Install
15
19
 
16
20
  ```sh
@@ -25,6 +29,9 @@ Dependencies: `requests`, `marshmallow-dataclass`, `py-ulid`.
25
29
  from kc_api import KcClient
26
30
 
27
31
  client = KcClient("YOUR_API_TOKEN") # api_url defaults to https://cloud-api.kvindo.ru
32
+ # TLS certificate verification is on by default (verify_ssl=True). Pass
33
+ # verify_ssl=False only to point this SDK at a genuinely self-hosted instance
34
+ # with a self-signed cert.
28
35
 
29
36
  # List (label-filtered, paginated)
30
37
  resp = client.vms.get_by_labels({"env": "prod"}, max_page_size=50)
@@ -66,7 +73,9 @@ Part of the Kvindo Cloud developer toolchain:
66
73
 
67
74
  - **[kc CLI](https://github.com/Kvindo/kc-cli)** — kubectl-style command-line client for Kvindo Cloud.
68
75
  - **[terraform-provider-kvindo](https://github.com/Kvindo/terraform-provider-kvindo)** — Terraform provider ([Registry](https://registry.terraform.io/providers/kvindo/kvindo/latest)).
76
+ - **[kc-mcp-server](https://github.com/Kvindo/kc-mcp-server)** — MCP server for Kvindo Cloud ([npm](https://www.npmjs.com/package/kc-mcp-server)), for managing resources from Claude Desktop/Code and other MCP clients.
69
77
  - **[Kvindo Cloud console](https://cloud.kvindo.com)** — web UI and API.
78
+ - **[Claude Code skill](.claude/skills/kvindo-python-sdk/SKILL.md)** — lets Claude script Kvindo Cloud with this SDK conversationally.
70
79
 
71
80
  ## License
72
81
 
@@ -46,7 +46,7 @@ logger = logging.getLogger(__name__)
46
46
  # requests, marshmallow-dataclass and py-ulid.
47
47
  def create_http_client_with_retries(
48
48
  retry_statuses=[500, 502, 503, 504, 520, 521],
49
- verify_ssl: bool = False,
49
+ verify_ssl: bool = True,
50
50
  ) -> requests.Session:
51
51
  """Build a `requests.Session` that retries idempotent failures with backoff.
52
52
 
@@ -55,8 +55,10 @@ def create_http_client_with_retries(
55
55
  server-side; 520 = web server returned an unknown error;
56
56
  521 = origin down (Cloudflare-specific).
57
57
  verify_ssl: enable/disable TLS certificate verification. Defaults to
58
- False because internal/dev endpoints use self-signed certs; pass
59
- True against public prod.
58
+ True every real Kvindo Cloud API host (dev and public prod) has
59
+ a valid, publicly-trusted certificate. Pass False only to point
60
+ this SDK at a genuinely self-hosted instance with a self-signed
61
+ cert.
60
62
 
61
63
  Returns:
62
64
  A configured `requests.Session` (reuse it for connection pooling).
@@ -143,6 +145,10 @@ class KcApiModificationErrorCode(Enum):
143
145
  """deleteProtection=true; clear it before deleting."""
144
146
  BadData = "BadData"
145
147
  """Request was malformed."""
148
+ QuotaExceeded = "QuotaExceeded"
149
+ """The organization's quota for this resource type/parameter would be exceeded, counting
150
+ resources that are submitted but not yet reconciled ("holds"). Not retryable - the caller
151
+ must delete resources or raise the quota. HTTP 409."""
146
152
 
147
153
 
148
154
  @dataclass
@@ -285,7 +291,7 @@ class KcResourceGetByLabelsResponse(object):
285
291
 
286
292
  # HTTP statuses the API uses to carry a structured (deserializable) body. Anything
287
293
  # outside this set is an unexpected transport/server failure and is raised instead.
288
- _HANDLED_STATUS_CODES = [200, 400, 401, 403, 422]
294
+ _HANDLED_STATUS_CODES = [200, 400, 401, 403, 409, 422]
289
295
 
290
296
 
291
297
  class KcResourceClient:
@@ -304,6 +310,7 @@ class KcResourceClient:
304
310
  token: str,
305
311
  api_url: str = "https://cloud-api.kvindo.ru",
306
312
  log_extra: dict = None,
313
+ verify_ssl: bool = True,
307
314
  ):
308
315
  """
309
316
  Args:
@@ -311,11 +318,16 @@ class KcResourceClient:
311
318
  token: the bearer token; a leading "Bearer " prefix is stripped if present.
312
319
  api_url: base URL of the Cloud API (no trailing slash).
313
320
  log_extra: optional dict merged into every debug log record's `extra`.
321
+ verify_ssl: enable/disable TLS certificate verification for every
322
+ request this client makes. Defaults to True; pass False only
323
+ to point this SDK at a genuinely self-hosted instance with a
324
+ self-signed cert.
314
325
  """
315
326
  self.__token = token.replace("Bearer ", "")
316
327
  self.__resource_type = resource_type
317
328
  self.__api_url = api_url
318
329
  self.__log_extra = log_extra if log_extra is not None else {}
330
+ self.__verify_ssl = verify_ssl
319
331
 
320
332
  def __headers(self) -> dict:
321
333
  """Standard auth + content-type headers for every request."""
@@ -342,7 +354,7 @@ class KcResourceClient:
342
354
  """
343
355
  url = f"{self.__api_url}/api/v1/{self.__resource_type}/{id}"
344
356
 
345
- response = create_http_client_with_retries().delete(url, headers=self.__headers())
357
+ response = create_http_client_with_retries(verify_ssl=self.__verify_ssl).delete(url, headers=self.__headers())
346
358
 
347
359
  logger.debug(
348
360
  f"Got {response.status_code} status code while making request DELETE {url}\nResponse body: {response.text}",
@@ -376,7 +388,7 @@ class KcResourceClient:
376
388
  """
377
389
  url = f"{self.__api_url}/api/v1/{self.__resource_type}/{id}"
378
390
 
379
- response = create_http_client_with_retries().get(url, headers=self.__headers())
391
+ response = create_http_client_with_retries(verify_ssl=self.__verify_ssl).get(url, headers=self.__headers())
380
392
 
381
393
  logger.debug(
382
394
  f"Got {response.status_code} status code while making request GET {url}\nResponse body: {response.text}",
@@ -418,7 +430,7 @@ class KcResourceClient:
418
430
  }
419
431
 
420
432
  url = create_url_with_query_params(url, params)
421
- response = create_http_client_with_retries().get(url, headers=self.__headers())
433
+ response = create_http_client_with_retries(verify_ssl=self.__verify_ssl).get(url, headers=self.__headers())
422
434
 
423
435
  logger.debug(
424
436
  f"Got {response.status_code} status code while making request GET {url}\nResponse body: {response.text}",
@@ -447,7 +459,7 @@ class KcResourceClient:
447
459
  """
448
460
  url = f"{self.__api_url}/api/v1/{self.__resource_type}/request/{request_id}"
449
461
 
450
- response = create_http_client_with_retries().get(url, headers=self.__headers())
462
+ response = create_http_client_with_retries(verify_ssl=self.__verify_ssl).get(url, headers=self.__headers())
451
463
 
452
464
  logger.debug(
453
465
  f"Got {response.status_code} status code while making request GET {url}\nResponse body: {response.text}",
@@ -533,7 +545,7 @@ class KcResourceClient:
533
545
 
534
546
  url = f"{self.__api_url}/api/v1/{self.__resource_type}"
535
547
 
536
- response = create_http_client_with_retries().put(url, json=data, headers=self.__headers())
548
+ response = create_http_client_with_retries(verify_ssl=self.__verify_ssl).put(url, json=data, headers=self.__headers())
537
549
 
538
550
  logger.debug(
539
551
  f"Got {response.status_code} status code while making request PUT {url}\nRequest body: {data}\nResponse body: {response.text}",
@@ -624,18 +636,13 @@ class KcClient:
624
636
  kubernetes_node_groups: KcResourceClient
625
637
  kubernetes_users: KcResourceClient
626
638
  kubernetes_user_roles: KcResourceClient
627
- postgresqls: KcResourceClient
628
639
  postgresql_standalones: KcResourceClient
629
- postgresql_node_groups: KcResourceClient
630
640
  postgresql_parameters_sets: KcResourceClient
631
- etcd: KcResourceClient
632
- etcd_node_group: KcResourceClient
633
641
  open_vpns: KcResourceClient
634
642
  open_vpn_users: KcResourceClient
635
643
  open_vpn_user_settings: KcResourceClient
636
644
  gitlabs: KcResourceClient
637
645
  gitlab_runners: KcResourceClient
638
- grafanas: KcResourceClient
639
646
  ollamas: KcResourceClient
640
647
 
641
648
  # IaM / org
@@ -658,6 +665,7 @@ class KcClient:
658
665
  token: str,
659
666
  api_url: str = "https://cloud-api.kvindo.ru",
660
667
  log_extra: dict = None,
668
+ verify_ssl: bool = True,
661
669
  ):
662
670
  """
663
671
  Args:
@@ -665,16 +673,21 @@ class KcClient:
665
673
  api_url: base URL of the Cloud API (no trailing slash).
666
674
  log_extra: optional dict merged into every debug log record's `extra`;
667
675
  propagated to every per-resource client.
676
+ verify_ssl: enable/disable TLS certificate verification for every
677
+ request this client (and every per-resource client it builds)
678
+ makes. Defaults to True; pass False only to point this SDK at
679
+ a genuinely self-hosted instance with a self-signed cert.
668
680
  """
669
681
  self.__log_extra = log_extra if log_extra is not None else {}
670
682
  self.__token = token.replace("Bearer ", "")
671
683
  self.__api_url = api_url
684
+ self.__verify_ssl = verify_ssl
672
685
  # Cached response of get_transaction_collection_keys (lazy, fetched once).
673
686
  self._transaction_collection_keys = None
674
687
 
675
688
  def _r(resource_type: str) -> KcResourceClient:
676
- """Build a per-type client sharing this client's token/url/log_extra."""
677
- return KcResourceClient(resource_type, token, api_url, log_extra)
689
+ """Build a per-type client sharing this client's token/url/log_extra/verify_ssl."""
690
+ return KcResourceClient(resource_type, token, api_url, log_extra, verify_ssl)
678
691
 
679
692
  # Compute
680
693
  self.vms = _r("vm")
@@ -726,18 +739,13 @@ class KcClient:
726
739
  self.kubernetes_node_groups = _r("kubernetes-node-group")
727
740
  self.kubernetes_users = _r("kubernetes-user")
728
741
  self.kubernetes_user_roles = _r("kubernetes-user-role")
729
- self.postgresqls = _r("postgresql")
730
742
  self.postgresql_standalones = _r("postgresql-standalone")
731
- self.postgresql_node_groups = _r("postgresql-node-group")
732
743
  self.postgresql_parameters_sets = _r("postgresql-parameters-set")
733
- self.etcd = _r("etcd")
734
- self.etcd_node_group = _r("etcd-node-group")
735
744
  self.open_vpns = _r("open-vpn")
736
745
  self.open_vpn_users = _r("open-vpn-user")
737
746
  self.open_vpn_user_settings = _r("open-vpn-user-settings")
738
747
  self.gitlabs = _r("gitlab")
739
748
  self.gitlab_runners = _r("gitlab-runner")
740
- self.grafanas = _r("grafana")
741
749
  self.ollamas = _r("ollama")
742
750
 
743
751
  # IaM / org
@@ -764,10 +772,22 @@ class KcClient:
764
772
 
765
773
  Returns:
766
774
  The raw list returned by the transaction-spec endpoint.
775
+
776
+ Raises:
777
+ Exception: on an unexpected HTTP status. Unlike the per-resource
778
+ methods, any non-200 here is treated as unhandled (this
779
+ endpoint has no typed error-code contract) — previously this
780
+ method cached whatever `.json()` returned regardless of status,
781
+ so a transient failure (e.g. an auth blip) got cached as if it
782
+ were the real key list, permanently, for this instance's life.
767
783
  """
768
784
  if self._transaction_collection_keys is None:
769
785
  url = f"{self.__api_url}/api/v1/internal/transaction-spec"
770
786
  headers = {"Authorization": f"Bearer {self.__token}"}
771
- response = create_http_client_with_retries().get(url, headers=headers)
787
+ response = create_http_client_with_retries(verify_ssl=self.__verify_ssl).get(url, headers=headers)
788
+ if response.status_code != 200:
789
+ raise Exception(
790
+ f"Got {response.status_code} status code while making request GET {url}\nResponse body: {response.text}"
791
+ )
772
792
  self._transaction_collection_keys = response.json()
773
793
  return self._transaction_collection_keys
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kc-sdk-python
3
- Version: 3.0.0
3
+ Version: 4.0.0
4
4
  Summary: Kvindo Cloud Python SDK — typed client for managing Kvindo Cloud infrastructure (VMs, S3, Kubernetes, load balancers, VPCs, PostgreSQL) via the REST API
5
5
  Author: Kvindo
6
6
  License-Expression: MIT
@@ -45,6 +45,10 @@ balancers, VPCs, VPNs, and managed PostgreSQL.
45
45
  A thin, typed client over the REST API: one resource client per resource type, all sharing the
46
46
  same create / read / update / delete / list contract.
47
47
 
48
+ > **Using Claude Code?** This repo ships a [Claude Code skill](.claude/skills/kvindo-python-sdk/SKILL.md)
49
+ > that teaches Claude how to script Kvindo Cloud with this SDK — clone this repo (or otherwise have
50
+ > it on disk) and open Claude Code there to pick it up automatically.
51
+
48
52
  ## Install
49
53
 
50
54
  ```sh
@@ -59,6 +63,9 @@ Dependencies: `requests`, `marshmallow-dataclass`, `py-ulid`.
59
63
  from kc_api import KcClient
60
64
 
61
65
  client = KcClient("YOUR_API_TOKEN") # api_url defaults to https://cloud-api.kvindo.ru
66
+ # TLS certificate verification is on by default (verify_ssl=True). Pass
67
+ # verify_ssl=False only to point this SDK at a genuinely self-hosted instance
68
+ # with a self-signed cert.
62
69
 
63
70
  # List (label-filtered, paginated)
64
71
  resp = client.vms.get_by_labels({"env": "prod"}, max_page_size=50)
@@ -100,7 +107,9 @@ Part of the Kvindo Cloud developer toolchain:
100
107
 
101
108
  - **[kc CLI](https://github.com/Kvindo/kc-cli)** — kubectl-style command-line client for Kvindo Cloud.
102
109
  - **[terraform-provider-kvindo](https://github.com/Kvindo/terraform-provider-kvindo)** — Terraform provider ([Registry](https://registry.terraform.io/providers/kvindo/kvindo/latest)).
110
+ - **[kc-mcp-server](https://github.com/Kvindo/kc-mcp-server)** — MCP server for Kvindo Cloud ([npm](https://www.npmjs.com/package/kc-mcp-server)), for managing resources from Claude Desktop/Code and other MCP clients.
103
111
  - **[Kvindo Cloud console](https://cloud.kvindo.com)** — web UI and API.
112
+ - **[Claude Code skill](.claude/skills/kvindo-python-sdk/SKILL.md)** — lets Claude script Kvindo Cloud with this SDK conversationally.
104
113
 
105
114
  ## License
106
115
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "kc-sdk-python"
7
- version = "3.0.0"
7
+ version = "4.0.0"
8
8
  description = "Kvindo Cloud Python SDK — typed client for managing Kvindo Cloud infrastructure (VMs, S3, Kubernetes, load balancers, VPCs, PostgreSQL) via the REST API"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
File without changes
File without changes