crossplane-function-pythonic 0.6.3__py3-none-any.whl → 0.7.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.
@@ -1,8 +1,6 @@
1
1
  from importlib.metadata import PackageNotFoundError, version
2
2
 
3
3
  try:
4
- __version__ = version(
5
- "crossplane-function-pythonic"
6
- ) # Use the exact [project.name] from pyproject.toml
4
+ __version__ = version("crossplane-function-pythonic")
7
5
  except PackageNotFoundError:
8
6
  __version__ = "0.0.0"
@@ -1,4 +1,13 @@
1
- def resource_ready(resource):
1
+ from typing import TYPE_CHECKING
2
+
3
+ if TYPE_CHECKING:
4
+ from . import (
5
+ composite,
6
+ protobuf,
7
+ )
8
+
9
+
10
+ def resource_ready(resource: composite.Resource) -> protobuf.Value | None:
2
11
  if not resource.observed:
3
12
  return None
4
13
  return _checks.get(
@@ -7,9 +16,9 @@ def resource_ready(resource):
7
16
 
8
17
 
9
18
  class ReadyCondition:
10
- def ready(self, resource):
19
+ def ready(self, resource: composite.Resource) -> protobuf.Value | None:
11
20
  ready = resource.conditions.Ready
12
- if not ready._find_condition():
21
+ if not ready._get_condition():
13
22
  return None
14
23
  if ready.status:
15
24
  return resource.observed.metadata.name
@@ -18,7 +27,7 @@ class ReadyCondition:
18
27
  return resource.status.notReadyCondition
19
28
 
20
29
 
21
- _checks = {}
30
+ _checks: dict[tuple, Check] = {}
22
31
  _check_default = ReadyCondition()
23
32
 
24
33
 
@@ -29,12 +38,12 @@ class Check:
29
38
  if hasattr(cls, "apiVersion"):
30
39
  _checks[(cls.apiVersion, cls.__name__)] = cls()
31
40
 
32
- def ready(self, resource):
41
+ def ready(self, resource: composite.Resource) -> protobuf.Value | None:
33
42
  raise NotImplementedError()
34
43
 
35
44
 
36
45
  class AlwaysReady(Check):
37
- def ready(self, resource):
46
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
38
47
  return resource.observed.metadata.name
39
48
 
40
49
 
@@ -53,7 +62,7 @@ class ConfigMap(AlwaysReady):
53
62
  class CronJob(Check):
54
63
  apiVersion = "batch/v1"
55
64
 
56
- def ready(self, resource):
65
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
57
66
  if resource.observed.spec.suspend and len(resource.observed.spec.suspend):
58
67
  return resource.observed.metadata.name
59
68
  if not resource.status.lastScheduleTime:
@@ -72,7 +81,7 @@ class CronJob(Check):
72
81
  class DaemonSet(Check):
73
82
  apiVersion = "apps/v1"
74
83
 
75
- def ready(self, resource):
84
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
76
85
  scheduled = resource.status.desiredNumberScheduled
77
86
  if not scheduled:
78
87
  return scheduled
@@ -88,7 +97,7 @@ class DaemonSet(Check):
88
97
  class Deployment(Check):
89
98
  apiVersion = "apps/v1"
90
99
 
91
- def ready(self, resource):
100
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
92
101
  replicas = resource.observed.spec.replicas or 1
93
102
  for field in ("updatedReplicas", "availableReplicas"):
94
103
  value = resource.status[field]
@@ -109,7 +118,7 @@ class Deployment(Check):
109
118
  class HorizontalPodAutoscaler(Check):
110
119
  apiVersion = "autoscaling/v2"
111
120
 
112
- def ready(self, resource):
121
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
113
122
  for type in (
114
123
  "FailedGetScale",
115
124
  "FailedUpdateScale",
@@ -121,22 +130,22 @@ class HorizontalPodAutoscaler(Check):
121
130
  for type in ("ScalingActive", "ScalingLimited"):
122
131
  if resource.conditions[type].status:
123
132
  return resource.observed.metadata.name
124
- return resource.status.notScalingActiveOrLimiited
133
+ return resource.status.notScalingActiveOrLimited
125
134
 
126
135
 
127
136
  class Ingress(Check):
128
137
  apiVersion = "networking.k8s.io/v1"
129
138
 
130
- def ready(self, resource):
139
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
131
140
  if not len(resource.status.loadBalancer.ingress):
132
- return resource.status.noLoadBalanceIngresses
141
+ return resource.status.noLoadBalancerIngresses
133
142
  return resource.observed.metadata.name
134
143
 
135
144
 
136
145
  class Job(Check):
137
146
  apiVersion = "batch/v1"
138
147
 
139
- def ready(self, resource):
148
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
140
149
  for type in ("Failed", "Suspended"):
141
150
  if resource.conditions[type].status:
142
151
  return resource.status[f"is{type}"]
@@ -157,7 +166,7 @@ class Namespace(AlwaysReady):
157
166
  class PersistentVolumeClaim(Check):
158
167
  apiVersion = "v1"
159
168
 
160
- def ready(self, resource):
169
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
161
170
  if resource.status.phase != "Bound":
162
171
  return resource.status.phaseNotBound
163
172
  return resource.observed.metadata.name
@@ -166,7 +175,7 @@ class PersistentVolumeClaim(Check):
166
175
  class Pod(Check):
167
176
  apiVersion = "v1"
168
177
 
169
- def ready(self, resource):
178
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
170
179
  if resource.status.phase == "Succeeded":
171
180
  return resource.observed.metadata.name
172
181
  if (
@@ -179,9 +188,9 @@ class Pod(Check):
179
188
 
180
189
 
181
190
  class ReplicaSet(Check):
182
- apiVersion = "v1"
191
+ apiVersion = "apps/v1"
183
192
 
184
- def ready(self, resource):
193
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
185
194
  if int(resource.status.observedGeneration) < int(
186
195
  resource.observed.metadata.generation
187
196
  ):
@@ -195,7 +204,7 @@ class ReplicaSet(Check):
195
204
  if int(resource.status.availableReplicas) < int(
196
205
  resource.observed.spec.replicas or 1
197
206
  ):
198
- return resource.status.tooFewavailableReplicas
207
+ return resource.status.tooFewAvailableReplicas
199
208
  return resource.observed.metadata.name
200
209
 
201
210
 
@@ -214,7 +223,7 @@ class Secret(AlwaysReady):
214
223
  class Service(Check):
215
224
  apiVersion = "v1"
216
225
 
217
- def ready(self, resource):
226
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
218
227
  if resource.observed.spec.type != "LoadBalancer":
219
228
  return resource.observed.metadata.name
220
229
  if not len(resource.status.loadBalancer.ingress):
@@ -229,7 +238,7 @@ class ServiceAccount(AlwaysReady):
229
238
  class StatefulSet(Check):
230
239
  apiVersion = "apps/v1"
231
240
 
232
- def ready(self, resource):
241
+ def ready(self, resource: composite.Resource) -> protobuf.Value:
233
242
  replicas = resource.observed.spec.replicas or 1
234
243
  for field in ("readyReplicas", "currentReplicas"):
235
244
  value = resource.status[field]
@@ -238,5 +247,5 @@ class StatefulSet(Check):
238
247
  if replicas != value:
239
248
  return resource.status[f"{field}NotReplicas"]
240
249
  if resource.status.currentRevision != resource.status.updateRevision:
241
- return resource.status.currentRevisionNotUpdateReivsion
250
+ return resource.status.currentRevisionNotUpdateRevision
242
251
  return resource.observed.metadata.name
@@ -1,27 +1,32 @@
1
+ import argparse
1
2
  import logging
2
3
  import pathlib
3
4
  import sys
4
5
 
5
6
 
6
7
  class Command:
7
- name = None
8
- command = None
9
- description = None
8
+ name: str | None = None
9
+ command: str | None = None
10
+ help: str | None = None
11
+ description: str | None = None
10
12
 
11
13
  @classmethod
12
- def create(cls, subparsers):
13
- parser = subparsers.add_parser(
14
- cls.name, help=cls.help, description=cls.description
15
- )
16
- parser.set_defaults(command=cls)
17
- cls.add_parser_arguments(parser)
14
+ def create(
15
+ cls, subparsers: argparse._SubParsersAction[argparse.ArgumentParser]
16
+ ) -> None:
17
+ if cls.name is not None:
18
+ parser: argparse.ArgumentParser = subparsers.add_parser(
19
+ cls.name, help=cls.help, description=cls.description
20
+ )
21
+ parser.set_defaults(command=cls)
22
+ cls.add_parser_arguments(parser)
18
23
 
19
24
  @classmethod
20
- def add_parser_arguments(cls, parser):
25
+ def add_parser_arguments(cls, parser: argparse.ArgumentParser) -> None:
21
26
  pass
22
27
 
23
28
  @classmethod
24
- def add_function_arguments(cls, parser):
29
+ def add_function_arguments(cls, parser: argparse.ArgumentParser) -> None:
25
30
  parser.add_argument(
26
31
  "--debug",
27
32
  "-d",
@@ -66,14 +71,14 @@ class Command:
66
71
  help="Enable Crossplane V1 compatibility mode",
67
72
  )
68
73
 
69
- def __init__(self, args=None):
70
- self.args = args
74
+ def __init__(self, args: argparse.Namespace | None = None) -> None:
75
+ self.args = args if args is not None else argparse.Namespace()
71
76
  self.initialize()
72
77
 
73
- def initialize(self):
78
+ def initialize(self) -> None:
74
79
  pass
75
80
 
76
- def initialize_function(self):
81
+ def initialize_function(self) -> None:
77
82
  formatter = Formatter(self.args.log_name_width)
78
83
  handler = logging.StreamHandler(sys.stdout)
79
84
  handler.setFormatter(formatter)
@@ -98,15 +103,16 @@ class Command:
98
103
  if self.args.allow_oversize_protos:
99
104
  from google.protobuf.internal import api_implementation
100
105
 
101
- if api_implementation._c_module:
102
- api_implementation._c_module.SetAllowOversizeProtos(True)
106
+ c_module = getattr(api_implementation, "_c_module", None)
107
+ if c_module:
108
+ c_module.SetAllowOversizeProtos(True)
103
109
 
104
- async def run(self):
110
+ async def run(self) -> None:
105
111
  raise NotImplementedError()
106
112
 
107
113
 
108
114
  class Formatter(logging.Formatter):
109
- def __init__(self, name_width):
115
+ def __init__(self, name_width: int):
110
116
  super().__init__(
111
117
  f"[{{asctime}}.{{msecs:03.0f}}] {{sname:{name_width}.{name_width}}} [{{levelname:8.8}}] {{message}}",
112
118
  "%Y-%m-%d %H:%M:%S",
@@ -114,16 +120,17 @@ class Formatter(logging.Formatter):
114
120
  )
115
121
  self.name_width = name_width
116
122
 
117
- def format(self, record):
118
- record.sname = record.name
119
- extra = len(record.sname) - self.name_width
123
+ def format(self, record: logging.LogRecord):
124
+ sname = record.name
125
+ extra = len(sname) - self.name_width
120
126
  if extra > 0:
121
- names = record.sname.split(".")
127
+ names = sname.split(".")
122
128
  for ix, name in enumerate(names):
123
129
  if len(name) > extra:
124
130
  names[ix] = name[extra:]
125
131
  break
126
132
  names[ix] = name[:1]
127
133
  extra -= len(name) - 1
128
- record.sname = ".".join(names)
134
+ sname = ".".join(names)
135
+ record.sname = sname
129
136
  return super().format(record)