crossplane-function-pythonic 0.1.4__tar.gz → 0.2.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.
Files changed (158) hide show
  1. crossplane_function_pythonic-0.1.4/README.md → crossplane_function_pythonic-0.2.0/PKG-INFO +106 -48
  2. crossplane_function_pythonic-0.1.4/PKG-INFO → crossplane_function_pythonic-0.2.0/README.md +82 -72
  3. crossplane_function_pythonic-0.2.0/crossplane/pythonic/__about__.py +2 -0
  4. crossplane_function_pythonic-0.2.0/crossplane/pythonic/__main__.py +2 -0
  5. crossplane_function_pythonic-0.2.0/crossplane/pythonic/command.py +102 -0
  6. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/crossplane/pythonic/composite.py +50 -23
  7. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/crossplane/pythonic/function.py +14 -10
  8. crossplane_function_pythonic-0.2.0/crossplane/pythonic/grpc.py +123 -0
  9. crossplane_function_pythonic-0.2.0/crossplane/pythonic/main.py +28 -0
  10. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/crossplane/pythonic/protobuf.py +9 -2
  11. crossplane_function_pythonic-0.2.0/crossplane/pythonic/render.py +432 -0
  12. crossplane_function_pythonic-0.2.0/crossplane/pythonic/version.py +13 -0
  13. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/.dev/functions.yaml +2 -2
  14. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/cluster-function-pythonic.yaml +1 -1
  15. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/composition.yaml +2 -2
  16. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/functions.yaml +2 -2
  17. crossplane_function_pythonic-0.2.0/examples/aks-cluster/render.sh +10 -0
  18. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/eks-cluster/composition-v2.yaml +3 -3
  19. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/eks-cluster/composition.yaml +3 -3
  20. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/eks-cluster/definition.yaml +3 -3
  21. {crossplane_function_pythonic-0.1.4/examples/import-existing-vpc → crossplane_function_pythonic-0.2.0/examples/eks-cluster}/functions.yaml +2 -2
  22. crossplane_function_pythonic-0.2.0/examples/eks-cluster/render-v2.sh +4 -0
  23. {crossplane_function_pythonic-0.1.4/examples/import-existing-vpc → crossplane_function_pythonic-0.2.0/examples/eks-cluster}/render.sh +1 -1
  24. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/eks-cluster/xr.yaml +2 -2
  25. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/composition.yaml +1 -1
  26. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/function.yaml +2 -2
  27. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/conditions/composition.yaml +1 -5
  28. crossplane_function_pythonic-0.2.0/examples/function-go-templating/conditions/functions.yaml +10 -0
  29. crossplane_function_pythonic-0.2.0/examples/function-go-templating/conditions/render.sh +4 -0
  30. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/context/composition.yaml +6 -17
  31. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/context/environmentConfigs.yaml +1 -1
  32. crossplane_function_pythonic-0.2.0/examples/function-go-templating/context/functions.yaml +10 -0
  33. crossplane_function_pythonic-0.2.0/examples/function-go-templating/context/render.sh +4 -0
  34. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/extra-resources/composition.yaml +1 -1
  35. {crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/fromYaml → crossplane_function_pythonic-0.2.0/examples/function-go-templating/extra-resources}/functions.yaml +2 -2
  36. crossplane_function_pythonic-0.2.0/examples/function-go-templating/extra-resources/render.sh +4 -0
  37. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/fromYaml/composition.yaml +1 -1
  38. {crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/getComposedResource → crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/fromYaml}/functions.yaml +2 -2
  39. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/fromYaml/render.sh +4 -0
  40. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getComposedResource/composition.yaml +1 -1
  41. {crossplane_function_pythonic-0.1.4/examples/function-go-templating/extra-resources → crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getComposedResource}/functions.yaml +2 -2
  42. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getComposedResource/render.sh +4 -0
  43. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getCompositeResource/composition.yaml +1 -1
  44. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getCompositeResource/functions.yaml +2 -2
  45. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getCompositeResource/render.sh +4 -0
  46. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getCredentialData/composition.yaml +27 -0
  47. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getCredentialData/credentials.yaml +9 -0
  48. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getCredentialData/functions.yaml +9 -0
  49. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getCredentialData/render.sh +4 -0
  50. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getCredentialData/xr.yaml +5 -0
  51. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getResourceCondition/composition.yaml +1 -1
  52. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getResourceCondition/functions.yaml +9 -0
  53. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/getResourceCondition/render.sh +4 -0
  54. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/include/composition.yaml +1 -1
  55. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/include/functions.yaml +9 -0
  56. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/include/render.sh +4 -0
  57. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/toYaml/composition.yaml +1 -1
  58. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/toYaml/functions.yaml +9 -0
  59. crossplane_function_pythonic-0.2.0/examples/function-go-templating/functions/toYaml/render.sh +4 -0
  60. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/inline/composition.yaml +1 -1
  61. crossplane_function_pythonic-0.2.0/examples/function-go-templating/inline/functions.yaml +9 -0
  62. crossplane_function_pythonic-0.2.0/examples/function-go-templating/inline/render.sh +4 -0
  63. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/recursive/composition-real.yaml +1 -1
  64. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/recursive/composition-wrapper.yaml +1 -1
  65. crossplane_function_pythonic-0.2.0/examples/function-go-templating/recursive/functions.yaml +9 -0
  66. crossplane_function_pythonic-0.2.0/examples/function-go-templating/recursive/render.sh +7 -0
  67. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/get-started-app/composition.yaml +1 -1
  68. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/get-started-app/functions.yaml +2 -2
  69. crossplane_function_pythonic-0.2.0/examples/get-started-app/render.sh +4 -0
  70. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/helm-copy-secret/composition.yaml +1 -1
  71. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/helm-copy-secret/functions.yaml +2 -2
  72. crossplane_function_pythonic-0.2.0/examples/helm-copy-secret/render.sh +4 -0
  73. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/helm-copy-secret/vcluster.py +1 -1
  74. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/import-existing-vpc/composition.yaml +2 -2
  75. {crossplane_function_pythonic-0.1.4/examples/eks-cluster → crossplane_function_pythonic-0.2.0/examples/import-existing-vpc}/functions.yaml +2 -2
  76. crossplane_function_pythonic-0.2.0/examples/import-existing-vpc/render.sh +7 -0
  77. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/import-existing-vpc/xr.yaml +1 -1
  78. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/single-purpose/functions.yaml +2 -2
  79. crossplane_function_pythonic-0.2.0/examples/single-purpose/render.sh +4 -0
  80. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/single-purpose/xr.yaml +1 -1
  81. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/usages-extra/composition.yaml +1 -1
  82. crossplane_function_pythonic-0.2.0/examples/usages-extra/functions.yaml +9 -0
  83. crossplane_function_pythonic-0.2.0/examples/usages-extra/render.sh +4 -0
  84. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/pyproject.toml +16 -16
  85. crossplane_function_pythonic-0.1.4/crossplane/pythonic/main.py +0 -198
  86. crossplane_function_pythonic-0.1.4/examples/aks-cluster/render.sh +0 -9
  87. crossplane_function_pythonic-0.1.4/examples/eks-cluster/render-v2.sh +0 -3
  88. crossplane_function_pythonic-0.1.4/examples/eks-cluster/render.sh +0 -3
  89. crossplane_function_pythonic-0.1.4/examples/function-go-templating/conditions/functions.yaml +0 -25
  90. crossplane_function_pythonic-0.1.4/examples/function-go-templating/conditions/render.sh +0 -3
  91. crossplane_function_pythonic-0.1.4/examples/function-go-templating/context/functions.yaml +0 -25
  92. crossplane_function_pythonic-0.1.4/examples/function-go-templating/context/render.sh +0 -3
  93. crossplane_function_pythonic-0.1.4/examples/function-go-templating/extra-resources/render.sh +0 -3
  94. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/fromYaml/render.sh +0 -3
  95. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/getComposedResource/render.sh +0 -3
  96. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/getCompositeResource/render.sh +0 -3
  97. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/getResourceCondition/functions.yaml +0 -9
  98. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/getResourceCondition/render.sh +0 -3
  99. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/include/functions.yaml +0 -9
  100. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/include/render.sh +0 -3
  101. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/toYaml/functions.yaml +0 -9
  102. crossplane_function_pythonic-0.1.4/examples/function-go-templating/functions/toYaml/render.sh +0 -3
  103. crossplane_function_pythonic-0.1.4/examples/function-go-templating/inline/functions.yaml +0 -9
  104. crossplane_function_pythonic-0.1.4/examples/function-go-templating/inline/render.sh +0 -3
  105. crossplane_function_pythonic-0.1.4/examples/function-go-templating/recursive/functions.yaml +0 -9
  106. crossplane_function_pythonic-0.1.4/examples/function-go-templating/recursive/render.sh +0 -4
  107. crossplane_function_pythonic-0.1.4/examples/get-started-app/render.sh +0 -3
  108. crossplane_function_pythonic-0.1.4/examples/helm-copy-secret/render.sh +0 -3
  109. crossplane_function_pythonic-0.1.4/examples/single-purpose/render.sh +0 -3
  110. crossplane_function_pythonic-0.1.4/examples/usages-extra/functions.yaml +0 -9
  111. crossplane_function_pythonic-0.1.4/examples/usages-extra/render.sh +0 -3
  112. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/.gitignore +0 -0
  113. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/LICENSE +0 -0
  114. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/crossplane/pythonic/__init__.py +0 -0
  115. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/crossplane/pythonic/packages.py +0 -0
  116. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/README.md +0 -0
  117. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/aks/kubernetescluster.py +0 -0
  118. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/aks/resourcegroup.py +0 -0
  119. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/definition.yaml +0 -0
  120. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/install.sh +0 -0
  121. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/kustomization.yaml +0 -0
  122. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/providers.yaml +0 -0
  123. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/aks-cluster/xr.yaml +0 -0
  124. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/README.md +0 -0
  125. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/definition.yaml +0 -0
  126. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/kustomization.yaml +0 -0
  127. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/runtime.yaml +0 -0
  128. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/vcluster.py +0 -0
  129. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/filing-system/vcluster.yaml +0 -0
  130. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/conditions/xr.yaml +0 -0
  131. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/conditions/xrd.yaml +0 -0
  132. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/context/xr.yaml +0 -0
  133. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/context/xrd.yaml +0 -0
  134. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/extra-resources/extraResources.yaml +0 -0
  135. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/extra-resources/xr.yaml +0 -0
  136. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/fromYaml/xr.yaml +0 -0
  137. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getComposedResource/observed.yaml +0 -0
  138. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getComposedResource/xr.yaml +0 -0
  139. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getCompositeResource/xr.yaml +0 -0
  140. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getResourceCondition/observed.yaml +0 -0
  141. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/getResourceCondition/xr.yaml +0 -0
  142. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/include/xr.yaml +0 -0
  143. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/functions/toYaml/xr.yaml +0 -0
  144. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/inline/xr.yaml +0 -0
  145. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/function-go-templating/recursive/xr.yaml +0 -0
  146. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/get-started-app/definition.yaml +0 -0
  147. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/get-started-app/xr.yaml +0 -0
  148. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/helm-copy-secret/kustomization.yaml +0 -0
  149. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/helm-copy-secret/run-function.sh +0 -0
  150. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/helm-copy-secret/xr.yaml +0 -0
  151. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/helm-copy-secret/xrd.yaml +0 -0
  152. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/import-existing-vpc/README.md +0 -0
  153. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/import-existing-vpc/definition.yaml +0 -0
  154. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/import-existing-vpc/observed.yaml +0 -0
  155. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/import-existing-vpc/provider-ec2.yaml +0 -0
  156. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/usages-extra/extraResources.yaml +0 -0
  157. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/usages-extra/observedResources.yaml +0 -0
  158. {crossplane_function_pythonic-0.1.4 → crossplane_function_pythonic-0.2.0}/examples/usages-extra/xr.yaml +0 -0
@@ -1,3 +1,27 @@
1
+ Metadata-Version: 2.4
2
+ Name: crossplane-function-pythonic
3
+ Version: 0.2.0
4
+ Summary: A Python centric Crossplane Function
5
+ Project-URL: Documentation, https://github.com/crossplane-contrib/function-pythonic#readme
6
+ Project-URL: Issues, https://github.com/crossplane-contrib/function-pythonic/issues
7
+ Project-URL: Source, https://github.com/crossplane-contrib/function-pythonic
8
+ Author-email: Patrick J McNerthney <pat@mcnerthney.com>
9
+ License-Expression: Apache-2.0
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Requires-Python: <3.15,>=3.12
17
+ Requires-Dist: crossplane-function-sdk-python==0.10.0
18
+ Requires-Dist: pyyaml==6.0.3
19
+ Provides-Extra: packages
20
+ Requires-Dist: kopf==1.39.1; extra == 'packages'
21
+ Provides-Extra: pip-install
22
+ Requires-Dist: pip==25.3; extra == 'pip-install'
23
+ Description-Content-Type: text/markdown
24
+
1
25
  # function-pythonic
2
26
 
3
27
  ## Introduction
@@ -21,11 +45,11 @@ spec:
21
45
  kind: XR
22
46
  mode: Pipeline
23
47
  pipeline:
24
- - step:
48
+ - step:
25
49
  functionRef:
26
50
  name: function-pythonic
27
51
  input:
28
- apiVersion: pythonic.fn.fortra.com/v1alpha1
52
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
29
53
  kind: Composite
30
54
  composite: |
31
55
  class VpcComposite(BaseComposite):
@@ -57,7 +81,7 @@ kind: Function
57
81
  metadata:
58
82
  name: function-pythonic
59
83
  spec:
60
- package: ghcr.io/fortra/function-pythonic:v0.1.3
84
+ package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.2.0
61
85
  ```
62
86
  ## Composed Resource Dependencies
63
87
 
@@ -203,7 +227,7 @@ The BaseComposite class provides the following fields for manipulating the Compo
203
227
  | self.spec | Map | The composite observed spec |
204
228
  | self.status | Map | The composite desired and observed status, read from observed if not in desired |
205
229
  | self.conditions | Conditions | The composite desired and observed conditions, read from observed if not in desired |
206
- | self.events | Events | Returned events against the Composite and optionally on the Claim |
230
+ | self.results | Results | Returned results applied to the Composite and optionally on the Claim |
207
231
  | self.connection | Connection | The composite desired and observed connection detials, read from observed if not in desired |
208
232
  | self.ready | Boolean | The composite desired ready state |
209
233
 
@@ -302,19 +326,19 @@ The fields are read only for `Resource.conditions` and `RequiredResource.conditi
302
326
  | Condition.lastTransitionTime | Timestamp | Last transition time, read only |
303
327
  | Condition.claim | Boolean | Also apply the condition the claim |
304
328
 
305
- ### Events
329
+ ### Results
306
330
 
307
- The `BaseComposite.events` field is a list of events to apply to the Composite and
331
+ The `BaseComposite.results` field is a list of results to apply to the Composite and
308
332
  optionally to the Claim.
309
333
 
310
334
  | Field | Type | Description |
311
335
  | ----- | ---- | ----------- |
312
- | Event.info | Boolean | Normal informational event |
313
- | Event.warning | Boolean | Warning level event |
314
- | Event.fatal | Boolean | Fatal events also terminate composing the Composite |
315
- | Event.reason | String | PascalCase, machine-readable reason for this event |
316
- | Event.message | String | Human-readable details about the event |
317
- | Event.claim | Boolean | Also apply the event to the claim |
336
+ | Result.info | Boolean | Normal informational result |
337
+ | Result.warning | Boolean | Warning level result |
338
+ | Result.fatal | Boolean | Fatal results also terminate composing the Composite |
339
+ | Result.reason | String | PascalCase, machine-readable reason for this result |
340
+ | Result.message | String | Human-readable details about the result |
341
+ | Result.claim | Boolean | Also apply the result to the claim |
318
342
 
319
343
  ## Single use Composites
320
344
 
@@ -324,7 +348,7 @@ just to run that Composition once in a single use or initialize task?
324
348
  function-pythonic installs a `Composite` CompositeResourceDefinition that enables
325
349
  creating such tasks using a single Composite resource:
326
350
  ```yaml
327
- apiVersion: pythonic.fortra.com/v1alpha1
351
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
328
352
  kind: Composite
329
353
  metadata:
330
354
  name: composite-example
@@ -337,16 +361,62 @@ spec:
337
361
 
338
362
  ## Quick Start Development
339
363
 
340
- The following example demonstrates how to locally render function-python
341
- compositions. First, install the `crossplane-function-pythonic` python
342
- package into the python environment:
364
+ function-pythonic includes a pure python implementation of the `crossplane render ...`
365
+ command, which can be used to render Compositions that only use function-pythonic. This
366
+ makes it very easy to test and debug using your IDE of choice. It is also blindingly
367
+ fast compared to `crossplane render`. To use, install the `crossplane-function-pythonic`
368
+ python package into the python environment.
343
369
  ```shell
344
370
  $ pip install crossplane-function-pythonic
345
371
  ```
346
- Next, create the following files:
372
+ Then to render function-pythonic Compositions, use the `function-pythonic render ...`
373
+ command.
374
+ ```shell
375
+ $ function-pythonic render --help
376
+ usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--python-path DIRECTORY] [--render-unknowns]
377
+ [--allow-oversize-protos] [--context-files KEY=PATH] [--context-values KEY=VALUE]
378
+ [--observed-resources PATH] [--extra-resources PATH] [--required-resources PATH]
379
+ [--function-credentials PATH] [--include-full-xr] [--include-function-results] [--include-context]
380
+ PATH [PATH/CLASS]
381
+
382
+ positional arguments:
383
+ PATH A YAML file containing the Composite resource to render.
384
+ PATH/CLASS A YAML file containing the Composition resource or the complete path of a function=-pythonic BaseComposite subclass.
385
+
386
+ options:
387
+ -h, --help show this help message and exit
388
+ --debug, -d Emit debug logs.
389
+ --log-name-width WIDTH
390
+ Width of the logger name in the log output, default 40.
391
+ --python-path DIRECTORY
392
+ Filing system directories to add to the python path.
393
+ --render-unknowns, -u
394
+ Render resources with unknowns, useful during local development.
395
+ --allow-oversize-protos
396
+ Allow oversized protobuf messages
397
+ --context-files KEY=PATH
398
+ Context key-value pairs to pass to the Function pipeline. Values must be files containing YAML/JSON.
399
+ --context-values KEY=VALUE
400
+ Context key-value pairs to pass to the Function pipeline. Values must be YAML/JSON. Keys take precedence over --context-files.
401
+ --observed-resources, -o PATH
402
+ A YAML file or directory of YAML files specifying the observed state of composed resources.
403
+ --extra-resources PATH
404
+ A YAML file or directory of YAML files specifying required resources (deprecated, use --required-resources).
405
+ --required-resources, -e PATH
406
+ A YAML file or directory of YAML files specifying required resources to pass to the Function pipeline.
407
+ --function-credentials PATH
408
+ A YAML file or directory of YAML files specifying credentials to use for Functions to render the XR.
409
+ --include-full-xr, -x
410
+ Include a direct copy of the input XR's spedc and metadata fields in the rendered output.
411
+ --include-function-results, -r
412
+ Include informational and warning messages from Functions in the rendered output as resources of kind: Result..
413
+ --include-context, -c
414
+ Include the context in the rendered output as a resource of kind: Context.
415
+ ```
416
+ The following example demonstrates how to locally render function-python compositions. First, create the following files:
347
417
  #### xr.yaml
348
418
  ```yaml
349
- apiVersion: pythonic.fortra.com/v1alpha1
419
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
350
420
  kind: Hello
351
421
  metadata:
352
422
  name: world
@@ -358,10 +428,10 @@ spec:
358
428
  apiVersion: apiextensions.crossplane.io/v1
359
429
  kind: Composition
360
430
  metadata:
361
- name: hellos.pythonic.fortra.com
431
+ name: hellos.pythonic.crossplane.io
362
432
  spec:
363
433
  compositeTypeRef:
364
- apiVersion: pythonic.fortra.com/v1alpha1
434
+ apiVersion: pythonic.crossplane.io/v1alpha1
365
435
  kind: Hello
366
436
  mode: Pipeline
367
437
  pipeline:
@@ -369,50 +439,38 @@ spec:
369
439
  functionRef:
370
440
  name: function-pythonic
371
441
  input:
372
- apiVersion: pythonic.fn.fortra.com/v1alpha1
442
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
373
443
  kind: Composite
374
444
  composite: |
375
445
  class GreetingComposite(BaseComposite):
376
446
  def compose(self):
377
447
  self.status.greeting = f"Hello, {self.spec.who}!"
378
448
  ```
379
- #### functions.yaml
380
- ```yaml
381
- apiVersion: pkg.crossplane.io/v1beta1
382
- kind: Function
383
- metadata:
384
- name: function-pythonic
385
- annotations:
386
- render.crossplane.io/runtime: Development
387
- spec:
388
- package: ghcr.io/fortra/function-pythonic:v0.1.3
389
- ```
390
- In one terminal session, run function-pythonic:
391
- ```shell
392
- $ function-pythonic --insecure --debug --render-unknowns
393
- [2025-08-21 15:32:37.966] grpc._cython.cygrpc [DEBUG ] Using AsyncIOEngine.POLLER as I/O engine
394
- ```
395
- In another terminal session, render the Composite:
449
+ Then, to render the above composite and composition, run:
396
450
  ```shell
397
- $ crossplane render xr.yaml composition.yaml functions.yaml
451
+ $ function-pythonic render --debug --render-unknowns xr.yaml composition.yaml
452
+ [2025-12-29 09:44:57.949] io.crossplane.fn.pythonic.Hello.world [DEBUG ] Starting compose, 1st step, 1st pass
453
+ [2025-12-29 09:44:57.949] io.crossplane.fn.pythonic.Hello.world [INFO ] Completed compose
398
454
  ---
399
- apiVersion: pythonic.fortra.com/v1alpha1
455
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
400
456
  kind: Hello
401
457
  metadata:
402
458
  name: world
403
459
  status:
404
460
  conditions:
405
- - lastTransitionTime: "2024-01-01T00:00:00Z"
461
+ - lastTransitionTime: '2026-01-01T00:00:00Z'
406
462
  reason: Available
407
- status: "True"
463
+ status: 'True'
408
464
  type: Ready
409
- - lastTransitionTime: "2024-01-01T00:00:00Z"
465
+ - lastTransitionTime: '2026-01-01T00:00:00Z'
410
466
  message: All resources are composed
411
467
  reason: AllComposed
412
- status: "True"
468
+ status: 'True'
413
469
  type: ResourcesComposed
414
470
  greeting: Hello, World!
415
471
  ```
472
+ Most of the examples contain a `render.sh` command which uses `function-pythonic render` to
473
+ render the example.
416
474
 
417
475
  ## ConfigMap Packages
418
476
 
@@ -441,7 +499,7 @@ Then, in your Composition:
441
499
  functionRef:
442
500
  name: function-pythonic
443
501
  input:
444
- apiVersion: pythonic.fn.fortra.com/v1alpha1
502
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
445
503
  kind: Composite
446
504
  composite: |
447
505
  from example.pythonic import features
@@ -473,7 +531,7 @@ data:
473
531
  functionRef:
474
532
  name: function-pythonic
475
533
  input:
476
- apiVersion: pythonic.fn.fortra.com/v1alpha1
534
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
477
535
  kind: Composite
478
536
  composite: example.pythonic.features.FeatureOneComposite
479
537
  ...
@@ -487,7 +545,7 @@ kind: Function
487
545
  metadata:
488
546
  name: function-pythonic
489
547
  spec:
490
- package: ghcr.io/fortra/function-pythonic:v0.1.3
548
+ package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.2.0
491
549
  runtimeConfigRef:
492
550
  name: function-pythonic
493
551
  ---
@@ -580,7 +638,7 @@ data:
580
638
  functionRef:
581
639
  name: function-pythonic
582
640
  input:
583
- apiVersion: pythonic.fn.fortra.com/v1alpha1
641
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
584
642
  kind: Composite
585
643
  parameters:
586
644
  who: World
@@ -1,27 +1,3 @@
1
- Metadata-Version: 2.4
2
- Name: crossplane-function-pythonic
3
- Version: 0.1.4
4
- Summary: A Python centric Crossplane Function
5
- Project-URL: Documentation, https://github.com/fortra/function-pythonic#readme
6
- Project-URL: Issues, https://github.com/fortra/function-pythonic/issues
7
- Project-URL: Source, https://github.com/fortra/function-pythonic
8
- Author-email: Patrick J McNerthney <pat@mcnerthney.com>
9
- License-Expression: Apache-2.0
10
- License-File: LICENSE
11
- Classifier: Development Status :: 4 - Beta
12
- Classifier: Programming Language :: Python
13
- Classifier: Programming Language :: Python :: 3.11
14
- Classifier: Programming Language :: Python :: 3.12
15
- Classifier: Programming Language :: Python :: 3.13
16
- Requires-Python: <3.14,>=3.11
17
- Requires-Dist: crossplane-function-sdk-python==0.9.0
18
- Requires-Dist: pyyaml==6.0.2
19
- Provides-Extra: packages
20
- Requires-Dist: kopf==1.38.0; extra == 'packages'
21
- Provides-Extra: pip-install
22
- Requires-Dist: pip==25.2; extra == 'pip-install'
23
- Description-Content-Type: text/markdown
24
-
25
1
  # function-pythonic
26
2
 
27
3
  ## Introduction
@@ -45,11 +21,11 @@ spec:
45
21
  kind: XR
46
22
  mode: Pipeline
47
23
  pipeline:
48
- - step:
24
+ - step:
49
25
  functionRef:
50
26
  name: function-pythonic
51
27
  input:
52
- apiVersion: pythonic.fn.fortra.com/v1alpha1
28
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
53
29
  kind: Composite
54
30
  composite: |
55
31
  class VpcComposite(BaseComposite):
@@ -81,7 +57,7 @@ kind: Function
81
57
  metadata:
82
58
  name: function-pythonic
83
59
  spec:
84
- package: ghcr.io/fortra/function-pythonic:v0.1.3
60
+ package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.2.0
85
61
  ```
86
62
  ## Composed Resource Dependencies
87
63
 
@@ -227,7 +203,7 @@ The BaseComposite class provides the following fields for manipulating the Compo
227
203
  | self.spec | Map | The composite observed spec |
228
204
  | self.status | Map | The composite desired and observed status, read from observed if not in desired |
229
205
  | self.conditions | Conditions | The composite desired and observed conditions, read from observed if not in desired |
230
- | self.events | Events | Returned events against the Composite and optionally on the Claim |
206
+ | self.results | Results | Returned results applied to the Composite and optionally on the Claim |
231
207
  | self.connection | Connection | The composite desired and observed connection detials, read from observed if not in desired |
232
208
  | self.ready | Boolean | The composite desired ready state |
233
209
 
@@ -326,19 +302,19 @@ The fields are read only for `Resource.conditions` and `RequiredResource.conditi
326
302
  | Condition.lastTransitionTime | Timestamp | Last transition time, read only |
327
303
  | Condition.claim | Boolean | Also apply the condition the claim |
328
304
 
329
- ### Events
305
+ ### Results
330
306
 
331
- The `BaseComposite.events` field is a list of events to apply to the Composite and
307
+ The `BaseComposite.results` field is a list of results to apply to the Composite and
332
308
  optionally to the Claim.
333
309
 
334
310
  | Field | Type | Description |
335
311
  | ----- | ---- | ----------- |
336
- | Event.info | Boolean | Normal informational event |
337
- | Event.warning | Boolean | Warning level event |
338
- | Event.fatal | Boolean | Fatal events also terminate composing the Composite |
339
- | Event.reason | String | PascalCase, machine-readable reason for this event |
340
- | Event.message | String | Human-readable details about the event |
341
- | Event.claim | Boolean | Also apply the event to the claim |
312
+ | Result.info | Boolean | Normal informational result |
313
+ | Result.warning | Boolean | Warning level result |
314
+ | Result.fatal | Boolean | Fatal results also terminate composing the Composite |
315
+ | Result.reason | String | PascalCase, machine-readable reason for this result |
316
+ | Result.message | String | Human-readable details about the result |
317
+ | Result.claim | Boolean | Also apply the result to the claim |
342
318
 
343
319
  ## Single use Composites
344
320
 
@@ -348,7 +324,7 @@ just to run that Composition once in a single use or initialize task?
348
324
  function-pythonic installs a `Composite` CompositeResourceDefinition that enables
349
325
  creating such tasks using a single Composite resource:
350
326
  ```yaml
351
- apiVersion: pythonic.fortra.com/v1alpha1
327
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
352
328
  kind: Composite
353
329
  metadata:
354
330
  name: composite-example
@@ -361,16 +337,62 @@ spec:
361
337
 
362
338
  ## Quick Start Development
363
339
 
364
- The following example demonstrates how to locally render function-python
365
- compositions. First, install the `crossplane-function-pythonic` python
366
- package into the python environment:
340
+ function-pythonic includes a pure python implementation of the `crossplane render ...`
341
+ command, which can be used to render Compositions that only use function-pythonic. This
342
+ makes it very easy to test and debug using your IDE of choice. It is also blindingly
343
+ fast compared to `crossplane render`. To use, install the `crossplane-function-pythonic`
344
+ python package into the python environment.
367
345
  ```shell
368
346
  $ pip install crossplane-function-pythonic
369
347
  ```
370
- Next, create the following files:
348
+ Then to render function-pythonic Compositions, use the `function-pythonic render ...`
349
+ command.
350
+ ```shell
351
+ $ function-pythonic render --help
352
+ usage: Crossplane Function Pythonic render [-h] [--debug] [--log-name-width WIDTH] [--python-path DIRECTORY] [--render-unknowns]
353
+ [--allow-oversize-protos] [--context-files KEY=PATH] [--context-values KEY=VALUE]
354
+ [--observed-resources PATH] [--extra-resources PATH] [--required-resources PATH]
355
+ [--function-credentials PATH] [--include-full-xr] [--include-function-results] [--include-context]
356
+ PATH [PATH/CLASS]
357
+
358
+ positional arguments:
359
+ PATH A YAML file containing the Composite resource to render.
360
+ PATH/CLASS A YAML file containing the Composition resource or the complete path of a function=-pythonic BaseComposite subclass.
361
+
362
+ options:
363
+ -h, --help show this help message and exit
364
+ --debug, -d Emit debug logs.
365
+ --log-name-width WIDTH
366
+ Width of the logger name in the log output, default 40.
367
+ --python-path DIRECTORY
368
+ Filing system directories to add to the python path.
369
+ --render-unknowns, -u
370
+ Render resources with unknowns, useful during local development.
371
+ --allow-oversize-protos
372
+ Allow oversized protobuf messages
373
+ --context-files KEY=PATH
374
+ Context key-value pairs to pass to the Function pipeline. Values must be files containing YAML/JSON.
375
+ --context-values KEY=VALUE
376
+ Context key-value pairs to pass to the Function pipeline. Values must be YAML/JSON. Keys take precedence over --context-files.
377
+ --observed-resources, -o PATH
378
+ A YAML file or directory of YAML files specifying the observed state of composed resources.
379
+ --extra-resources PATH
380
+ A YAML file or directory of YAML files specifying required resources (deprecated, use --required-resources).
381
+ --required-resources, -e PATH
382
+ A YAML file or directory of YAML files specifying required resources to pass to the Function pipeline.
383
+ --function-credentials PATH
384
+ A YAML file or directory of YAML files specifying credentials to use for Functions to render the XR.
385
+ --include-full-xr, -x
386
+ Include a direct copy of the input XR's spedc and metadata fields in the rendered output.
387
+ --include-function-results, -r
388
+ Include informational and warning messages from Functions in the rendered output as resources of kind: Result..
389
+ --include-context, -c
390
+ Include the context in the rendered output as a resource of kind: Context.
391
+ ```
392
+ The following example demonstrates how to locally render function-python compositions. First, create the following files:
371
393
  #### xr.yaml
372
394
  ```yaml
373
- apiVersion: pythonic.fortra.com/v1alpha1
395
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
374
396
  kind: Hello
375
397
  metadata:
376
398
  name: world
@@ -382,10 +404,10 @@ spec:
382
404
  apiVersion: apiextensions.crossplane.io/v1
383
405
  kind: Composition
384
406
  metadata:
385
- name: hellos.pythonic.fortra.com
407
+ name: hellos.pythonic.crossplane.io
386
408
  spec:
387
409
  compositeTypeRef:
388
- apiVersion: pythonic.fortra.com/v1alpha1
410
+ apiVersion: pythonic.crossplane.io/v1alpha1
389
411
  kind: Hello
390
412
  mode: Pipeline
391
413
  pipeline:
@@ -393,50 +415,38 @@ spec:
393
415
  functionRef:
394
416
  name: function-pythonic
395
417
  input:
396
- apiVersion: pythonic.fn.fortra.com/v1alpha1
418
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
397
419
  kind: Composite
398
420
  composite: |
399
421
  class GreetingComposite(BaseComposite):
400
422
  def compose(self):
401
423
  self.status.greeting = f"Hello, {self.spec.who}!"
402
424
  ```
403
- #### functions.yaml
404
- ```yaml
405
- apiVersion: pkg.crossplane.io/v1beta1
406
- kind: Function
407
- metadata:
408
- name: function-pythonic
409
- annotations:
410
- render.crossplane.io/runtime: Development
411
- spec:
412
- package: ghcr.io/fortra/function-pythonic:v0.1.3
413
- ```
414
- In one terminal session, run function-pythonic:
415
- ```shell
416
- $ function-pythonic --insecure --debug --render-unknowns
417
- [2025-08-21 15:32:37.966] grpc._cython.cygrpc [DEBUG ] Using AsyncIOEngine.POLLER as I/O engine
418
- ```
419
- In another terminal session, render the Composite:
425
+ Then, to render the above composite and composition, run:
420
426
  ```shell
421
- $ crossplane render xr.yaml composition.yaml functions.yaml
427
+ $ function-pythonic render --debug --render-unknowns xr.yaml composition.yaml
428
+ [2025-12-29 09:44:57.949] io.crossplane.fn.pythonic.Hello.world [DEBUG ] Starting compose, 1st step, 1st pass
429
+ [2025-12-29 09:44:57.949] io.crossplane.fn.pythonic.Hello.world [INFO ] Completed compose
422
430
  ---
423
- apiVersion: pythonic.fortra.com/v1alpha1
431
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
424
432
  kind: Hello
425
433
  metadata:
426
434
  name: world
427
435
  status:
428
436
  conditions:
429
- - lastTransitionTime: "2024-01-01T00:00:00Z"
437
+ - lastTransitionTime: '2026-01-01T00:00:00Z'
430
438
  reason: Available
431
- status: "True"
439
+ status: 'True'
432
440
  type: Ready
433
- - lastTransitionTime: "2024-01-01T00:00:00Z"
441
+ - lastTransitionTime: '2026-01-01T00:00:00Z'
434
442
  message: All resources are composed
435
443
  reason: AllComposed
436
- status: "True"
444
+ status: 'True'
437
445
  type: ResourcesComposed
438
446
  greeting: Hello, World!
439
447
  ```
448
+ Most of the examples contain a `render.sh` command which uses `function-pythonic render` to
449
+ render the example.
440
450
 
441
451
  ## ConfigMap Packages
442
452
 
@@ -465,7 +475,7 @@ Then, in your Composition:
465
475
  functionRef:
466
476
  name: function-pythonic
467
477
  input:
468
- apiVersion: pythonic.fn.fortra.com/v1alpha1
478
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
469
479
  kind: Composite
470
480
  composite: |
471
481
  from example.pythonic import features
@@ -497,7 +507,7 @@ data:
497
507
  functionRef:
498
508
  name: function-pythonic
499
509
  input:
500
- apiVersion: pythonic.fn.fortra.com/v1alpha1
510
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
501
511
  kind: Composite
502
512
  composite: example.pythonic.features.FeatureOneComposite
503
513
  ...
@@ -511,7 +521,7 @@ kind: Function
511
521
  metadata:
512
522
  name: function-pythonic
513
523
  spec:
514
- package: ghcr.io/fortra/function-pythonic:v0.1.3
524
+ package: xpkg.upbound.io/crossplane-contrib/function-pythonic:v0.2.0
515
525
  runtimeConfigRef:
516
526
  name: function-pythonic
517
527
  ---
@@ -604,7 +614,7 @@ data:
604
614
  functionRef:
605
615
  name: function-pythonic
606
616
  input:
607
- apiVersion: pythonic.fn.fortra.com/v1alpha1
617
+ apiVersion: pythonic.fn.crossplane.io/v1alpha1
608
618
  kind: Composite
609
619
  parameters:
610
620
  who: World
@@ -0,0 +1,2 @@
1
+ # This is set at build time, using "hatch version"
2
+ __version__ = "0.2.0"
@@ -0,0 +1,2 @@
1
+ from . import main
2
+ main.main()
@@ -0,0 +1,102 @@
1
+
2
+ import logging
3
+ import pathlib
4
+ import sys
5
+
6
+
7
+ class Command:
8
+ name = None
9
+ command = None
10
+ description = None
11
+
12
+ @classmethod
13
+ def create(cls, subparsers):
14
+ parser = subparsers.add_parser(cls.name, help=cls.help, description=cls.description)
15
+ parser.set_defaults(command=cls)
16
+ cls.add_parser_arguments(parser)
17
+
18
+ @classmethod
19
+ def add_parser_arguments(cls, parser):
20
+ pass
21
+
22
+ @classmethod
23
+ def add_function_arguments(cls, parser):
24
+ parser.add_argument(
25
+ '--debug', '-d',
26
+ action='store_true',
27
+ help='Emit debug logs.',
28
+ )
29
+ parser.add_argument(
30
+ '--log-name-width',
31
+ type=int,
32
+ default=40,
33
+ metavar='WIDTH',
34
+ help='Width of the logger name in the log output, default 40.',
35
+ )
36
+ parser.add_argument(
37
+ '--python-path',
38
+ action='append',
39
+ default=[],
40
+ metavar='DIRECTORY',
41
+ help='Filing system directories to add to the python path.',
42
+ )
43
+ parser.add_argument(
44
+ '--render-unknowns', '-u',
45
+ action='store_true',
46
+ help='Render resources with unknowns, useful during local development.'
47
+ )
48
+ parser.add_argument(
49
+ '--allow-oversize-protos',
50
+ action='store_true',
51
+ help='Allow oversized protobuf messages',
52
+ )
53
+
54
+ def __init__(self, args):
55
+ self.args = args
56
+ self.initialize()
57
+
58
+ def initialize(self):
59
+ pass
60
+
61
+ def initialize_function(self):
62
+ formatter = Formatter(self.args.log_name_width)
63
+ handler = logging.StreamHandler(sys.stdout)
64
+ handler.setFormatter(formatter)
65
+ logger = logging.getLogger()
66
+ logger.handlers = [handler]
67
+ logger.setLevel(logging.DEBUG if self.args.debug else logging.INFO)
68
+
69
+ for path in reversed(self.args.python_path):
70
+ sys.path.insert(0, str(pathlib.Path(path).expanduser().resolve()))
71
+
72
+ if self.args.allow_oversize_protos:
73
+ from google.protobuf.internal import api_implementation
74
+ if api_implementation._c_module:
75
+ api_implementation._c_module.SetAllowOversizeProtos(True)
76
+
77
+ async def run(self):
78
+ raise NotImplementedError()
79
+
80
+
81
+ class Formatter(logging.Formatter):
82
+ def __init__(self, name_width):
83
+ super(Formatter, self).__init__(
84
+ f"[{{asctime}}.{{msecs:03.0f}}] {{sname:{name_width}.{name_width}}} [{{levelname:8.8}}] {{message}}",
85
+ '%Y-%m-%d %H:%M:%S',
86
+ '{',
87
+ )
88
+ self.name_width = name_width
89
+
90
+ def format(self, record):
91
+ record.sname = record.name
92
+ extra = len(record.sname) - self.name_width
93
+ if extra > 0:
94
+ names = record.sname.split('.')
95
+ for ix, name in enumerate(names):
96
+ if len(name) > extra:
97
+ names[ix] = name[extra:]
98
+ break
99
+ names[ix] = name[:1]
100
+ extra -= len(name) - 1
101
+ record.sname = '.'.join(names)
102
+ return super(Formatter, self).format(record)