py-serverless-kit 0.1.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 (223) hide show
  1. py_serverless_kit-0.1.0/.gitignore +28 -0
  2. py_serverless_kit-0.1.0/CHANGELOG.md +20 -0
  3. py_serverless_kit-0.1.0/CONTRIBUTING.md +13 -0
  4. py_serverless_kit-0.1.0/LICENSE +21 -0
  5. py_serverless_kit-0.1.0/PKG-INFO +300 -0
  6. py_serverless_kit-0.1.0/README.md +256 -0
  7. py_serverless_kit-0.1.0/deploy_docs/CONTRIBUTING.md +158 -0
  8. py_serverless_kit-0.1.0/docs/README.md +22 -0
  9. py_serverless_kit-0.1.0/docs/architecture.md +125 -0
  10. py_serverless_kit-0.1.0/docs/cli.md +175 -0
  11. py_serverless_kit-0.1.0/docs/configuration.md +245 -0
  12. py_serverless_kit-0.1.0/docs/dashboard.md +44 -0
  13. py_serverless_kit-0.1.0/docs/events.md +213 -0
  14. py_serverless_kit-0.1.0/docs/getting-started.md +176 -0
  15. py_serverless_kit-0.1.0/docs/handlers.md +219 -0
  16. py_serverless_kit-0.1.0/docs/local-development.md +98 -0
  17. py_serverless_kit-0.1.0/docs/migrating-from-aws.md +98 -0
  18. py_serverless_kit-0.1.0/docs/providers.md +354 -0
  19. py_serverless_kit-0.1.0/docs/troubleshooting.md +108 -0
  20. py_serverless_kit-0.1.0/docs/workflows.md +180 -0
  21. py_serverless_kit-0.1.0/examples/01-hello-http/README.md +53 -0
  22. py_serverless_kit-0.1.0/examples/01-hello-http/app/__init__.py +0 -0
  23. py_serverless_kit-0.1.0/examples/01-hello-http/app/handlers.py +15 -0
  24. py_serverless_kit-0.1.0/examples/01-hello-http/pskit.yml +24 -0
  25. py_serverless_kit-0.1.0/examples/01-hello-http/requirements.txt +1 -0
  26. py_serverless_kit-0.1.0/examples/02-rest-api/README.md +77 -0
  27. py_serverless_kit-0.1.0/examples/02-rest-api/app/__init__.py +0 -0
  28. py_serverless_kit-0.1.0/examples/02-rest-api/app/handlers.py +116 -0
  29. py_serverless_kit-0.1.0/examples/02-rest-api/app/store.py +50 -0
  30. py_serverless_kit-0.1.0/examples/02-rest-api/pskit.yml +82 -0
  31. py_serverless_kit-0.1.0/examples/02-rest-api/requirements.txt +1 -0
  32. py_serverless_kit-0.1.0/examples/03-scheduled-jobs/README.md +56 -0
  33. py_serverless_kit-0.1.0/examples/03-scheduled-jobs/app/__init__.py +0 -0
  34. py_serverless_kit-0.1.0/examples/03-scheduled-jobs/app/jobs.py +51 -0
  35. py_serverless_kit-0.1.0/examples/03-scheduled-jobs/pskit.yml +49 -0
  36. py_serverless_kit-0.1.0/examples/03-scheduled-jobs/requirements.txt +1 -0
  37. py_serverless_kit-0.1.0/examples/04-queue-worker/README.md +80 -0
  38. py_serverless_kit-0.1.0/examples/04-queue-worker/app/__init__.py +0 -0
  39. py_serverless_kit-0.1.0/examples/04-queue-worker/app/worker.py +75 -0
  40. py_serverless_kit-0.1.0/examples/04-queue-worker/pskit.yml +39 -0
  41. py_serverless_kit-0.1.0/examples/04-queue-worker/requirements.txt +1 -0
  42. py_serverless_kit-0.1.0/examples/05-storage-events/README.md +58 -0
  43. py_serverless_kit-0.1.0/examples/05-storage-events/app/__init__.py +0 -0
  44. py_serverless_kit-0.1.0/examples/05-storage-events/app/files.py +51 -0
  45. py_serverless_kit-0.1.0/examples/05-storage-events/pskit.yml +54 -0
  46. py_serverless_kit-0.1.0/examples/05-storage-events/requirements.txt +1 -0
  47. py_serverless_kit-0.1.0/examples/06-pubsub-topic/README.md +62 -0
  48. py_serverless_kit-0.1.0/examples/06-pubsub-topic/app/__init__.py +0 -0
  49. py_serverless_kit-0.1.0/examples/06-pubsub-topic/app/subscribers.py +41 -0
  50. py_serverless_kit-0.1.0/examples/06-pubsub-topic/pskit.yml +27 -0
  51. py_serverless_kit-0.1.0/examples/06-pubsub-topic/requirements.txt +1 -0
  52. py_serverless_kit-0.1.0/examples/07-workflow-orders/README.md +110 -0
  53. py_serverless_kit-0.1.0/examples/07-workflow-orders/app/__init__.py +0 -0
  54. py_serverless_kit-0.1.0/examples/07-workflow-orders/app/orders.py +84 -0
  55. py_serverless_kit-0.1.0/examples/07-workflow-orders/events/b2b.json +5 -0
  56. py_serverless_kit-0.1.0/examples/07-workflow-orders/events/declined.json +5 -0
  57. py_serverless_kit-0.1.0/examples/07-workflow-orders/events/happy.json +9 -0
  58. py_serverless_kit-0.1.0/examples/07-workflow-orders/pskit.yml +99 -0
  59. py_serverless_kit-0.1.0/examples/07-workflow-orders/requirements.txt +1 -0
  60. py_serverless_kit-0.1.0/examples/08-multi-cloud/README.md +71 -0
  61. py_serverless_kit-0.1.0/examples/08-multi-cloud/app/__init__.py +0 -0
  62. py_serverless_kit-0.1.0/examples/08-multi-cloud/app/handlers.py +45 -0
  63. py_serverless_kit-0.1.0/examples/08-multi-cloud/pskit.aws.yml +15 -0
  64. py_serverless_kit-0.1.0/examples/08-multi-cloud/pskit.azure.yml +12 -0
  65. py_serverless_kit-0.1.0/examples/08-multi-cloud/pskit.gcp.yml +11 -0
  66. py_serverless_kit-0.1.0/examples/08-multi-cloud/pskit.yml +90 -0
  67. py_serverless_kit-0.1.0/examples/08-multi-cloud/requirements.txt +1 -0
  68. py_serverless_kit-0.1.0/examples/09-function-invoke/README.md +61 -0
  69. py_serverless_kit-0.1.0/examples/09-function-invoke/app/__init__.py +0 -0
  70. py_serverless_kit-0.1.0/examples/09-function-invoke/app/quotes.py +44 -0
  71. py_serverless_kit-0.1.0/examples/09-function-invoke/pskit.yml +41 -0
  72. py_serverless_kit-0.1.0/examples/09-function-invoke/requirements.txt +1 -0
  73. py_serverless_kit-0.1.0/examples/10-stages-and-config/.env.example +5 -0
  74. py_serverless_kit-0.1.0/examples/10-stages-and-config/README.md +78 -0
  75. py_serverless_kit-0.1.0/examples/10-stages-and-config/app/__init__.py +0 -0
  76. py_serverless_kit-0.1.0/examples/10-stages-and-config/app/handlers.py +17 -0
  77. py_serverless_kit-0.1.0/examples/10-stages-and-config/app/settings.py +37 -0
  78. py_serverless_kit-0.1.0/examples/10-stages-and-config/config/limits.json +5 -0
  79. py_serverless_kit-0.1.0/examples/10-stages-and-config/pskit.yml +58 -0
  80. py_serverless_kit-0.1.0/examples/10-stages-and-config/requirements.txt +1 -0
  81. py_serverless_kit-0.1.0/examples/11-custom-terraform/README.md +83 -0
  82. py_serverless_kit-0.1.0/examples/11-custom-terraform/app/__init__.py +0 -0
  83. py_serverless_kit-0.1.0/examples/11-custom-terraform/app/handlers.py +21 -0
  84. py_serverless_kit-0.1.0/examples/11-custom-terraform/app/repository.py +56 -0
  85. py_serverless_kit-0.1.0/examples/11-custom-terraform/pskit.yml +64 -0
  86. py_serverless_kit-0.1.0/examples/11-custom-terraform/requirements.txt +1 -0
  87. py_serverless_kit-0.1.0/examples/11-custom-terraform/scripts/smoke_test.py +26 -0
  88. py_serverless_kit-0.1.0/examples/11-custom-terraform/tests/test_orders.py +11 -0
  89. py_serverless_kit-0.1.0/examples/12-async-and-context/README.md +61 -0
  90. py_serverless_kit-0.1.0/examples/12-async-and-context/app/__init__.py +0 -0
  91. py_serverless_kit-0.1.0/examples/12-async-and-context/app/handlers.py +65 -0
  92. py_serverless_kit-0.1.0/examples/12-async-and-context/pskit.yml +30 -0
  93. py_serverless_kit-0.1.0/examples/12-async-and-context/requirements.txt +1 -0
  94. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/README.md +120 -0
  95. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/after/app/__init__.py +0 -0
  96. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/after/app/orders.py +57 -0
  97. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/after/pskit.yml +55 -0
  98. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/after/requirements.txt +1 -0
  99. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/before/lambda_function.py +67 -0
  100. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/before/state_machine.asl.json +25 -0
  101. py_serverless_kit-0.1.0/examples/13-migrate-from-aws-lambda/before/template.yaml +36 -0
  102. py_serverless_kit-0.1.0/examples/14-testing/README.md +45 -0
  103. py_serverless_kit-0.1.0/examples/14-testing/app/__init__.py +0 -0
  104. py_serverless_kit-0.1.0/examples/14-testing/app/handlers.py +44 -0
  105. py_serverless_kit-0.1.0/examples/14-testing/ci.github-workflow.yml +43 -0
  106. py_serverless_kit-0.1.0/examples/14-testing/pskit.yml +39 -0
  107. py_serverless_kit-0.1.0/examples/14-testing/requirements.txt +1 -0
  108. py_serverless_kit-0.1.0/examples/14-testing/tests/conftest.py +20 -0
  109. py_serverless_kit-0.1.0/examples/14-testing/tests/test_handlers.py +62 -0
  110. py_serverless_kit-0.1.0/examples/14-testing/tests/test_workflow.py +31 -0
  111. py_serverless_kit-0.1.0/examples/15-ci-cd-deploy/README.md +64 -0
  112. py_serverless_kit-0.1.0/examples/15-ci-cd-deploy/app/__init__.py +0 -0
  113. py_serverless_kit-0.1.0/examples/15-ci-cd-deploy/app/handlers.py +12 -0
  114. py_serverless_kit-0.1.0/examples/15-ci-cd-deploy/deploy.github-workflow.yml +100 -0
  115. py_serverless_kit-0.1.0/examples/15-ci-cd-deploy/pskit.yml +50 -0
  116. py_serverless_kit-0.1.0/examples/15-ci-cd-deploy/requirements.txt +1 -0
  117. py_serverless_kit-0.1.0/examples/README.md +39 -0
  118. py_serverless_kit-0.1.0/pyproject.toml +95 -0
  119. py_serverless_kit-0.1.0/src/py_serverless_kit/__init__.py +47 -0
  120. py_serverless_kit-0.1.0/src/py_serverless_kit/__main__.py +3 -0
  121. py_serverless_kit-0.1.0/src/py_serverless_kit/_version.py +2 -0
  122. py_serverless_kit-0.1.0/src/py_serverless_kit/cli/__init__.py +0 -0
  123. py_serverless_kit-0.1.0/src/py_serverless_kit/cli/main.py +491 -0
  124. py_serverless_kit-0.1.0/src/py_serverless_kit/cli/templates.py +212 -0
  125. py_serverless_kit-0.1.0/src/py_serverless_kit/config/__init__.py +12 -0
  126. py_serverless_kit-0.1.0/src/py_serverless_kit/config/loader.py +316 -0
  127. py_serverless_kit-0.1.0/src/py_serverless_kit/config/schema.py +457 -0
  128. py_serverless_kit-0.1.0/src/py_serverless_kit/core/__init__.py +0 -0
  129. py_serverless_kit-0.1.0/src/py_serverless_kit/core/deployer.py +180 -0
  130. py_serverless_kit-0.1.0/src/py_serverless_kit/core/describe.py +112 -0
  131. py_serverless_kit-0.1.0/src/py_serverless_kit/core/project.py +147 -0
  132. py_serverless_kit-0.1.0/src/py_serverless_kit/dashboard/__init__.py +3 -0
  133. py_serverless_kit-0.1.0/src/py_serverless_kit/dashboard/generator.py +65 -0
  134. py_serverless_kit-0.1.0/src/py_serverless_kit/dashboard/template.html +248 -0
  135. py_serverless_kit-0.1.0/src/py_serverless_kit/local/__init__.py +3 -0
  136. py_serverless_kit-0.1.0/src/py_serverless_kit/local/runner.py +234 -0
  137. py_serverless_kit-0.1.0/src/py_serverless_kit/local/server.py +200 -0
  138. py_serverless_kit-0.1.0/src/py_serverless_kit/packaging/__init__.py +3 -0
  139. py_serverless_kit-0.1.0/src/py_serverless_kit/packaging/builder.py +252 -0
  140. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/__init__.py +15 -0
  141. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/alibaba.py +268 -0
  142. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/aws.py +508 -0
  143. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/azure.py +417 -0
  144. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/base.py +310 -0
  145. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/cloudflare.py +264 -0
  146. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/digitalocean.py +211 -0
  147. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/gcp.py +480 -0
  148. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/huawei.py +292 -0
  149. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/ibm.py +132 -0
  150. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/oracle.py +304 -0
  151. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/registry.py +60 -0
  152. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/schedule.py +153 -0
  153. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/tencent.py +275 -0
  154. py_serverless_kit-0.1.0/src/py_serverless_kit/providers/terraform_doc.py +125 -0
  155. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/__init__.py +6 -0
  156. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/__init__.py +18 -0
  157. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/_httpfn.py +91 -0
  158. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/alibaba.py +147 -0
  159. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/aws.py +201 -0
  160. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/azure.py +185 -0
  161. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/base.py +86 -0
  162. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/cloudflare.py +126 -0
  163. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/digitalocean.py +74 -0
  164. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/gcp.py +176 -0
  165. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/huawei.py +173 -0
  166. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/ibm.py +91 -0
  167. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/oracle.py +161 -0
  168. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/adapters/tencent.py +151 -0
  169. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/batch.py +47 -0
  170. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/context.py +45 -0
  171. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/dispatch.py +277 -0
  172. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/errors.py +83 -0
  173. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/event.py +267 -0
  174. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/invoke.py +119 -0
  175. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/log.py +69 -0
  176. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/manifest.py +121 -0
  177. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/response.py +177 -0
  178. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/routing.py +74 -0
  179. py_serverless_kit-0.1.0/src/py_serverless_kit/runtime/workflow.py +312 -0
  180. py_serverless_kit-0.1.0/src/py_serverless_kit/terraform/__init__.py +3 -0
  181. py_serverless_kit-0.1.0/src/py_serverless_kit/terraform/runner.py +104 -0
  182. py_serverless_kit-0.1.0/src/py_serverless_kit/workflows/__init__.py +35 -0
  183. py_serverless_kit-0.1.0/src/py_serverless_kit/workflows/asl.py +170 -0
  184. py_serverless_kit-0.1.0/src/py_serverless_kit/workflows/gcp.py +328 -0
  185. py_serverless_kit-0.1.0/tests/__init__.py +0 -0
  186. py_serverless_kit-0.1.0/tests/config/__init__.py +0 -0
  187. py_serverless_kit-0.1.0/tests/config/test_loader.py +211 -0
  188. py_serverless_kit-0.1.0/tests/config/test_schema.py +79 -0
  189. py_serverless_kit-0.1.0/tests/conftest.py +129 -0
  190. py_serverless_kit-0.1.0/tests/local/__init__.py +0 -0
  191. py_serverless_kit-0.1.0/tests/local/test_server.py +110 -0
  192. py_serverless_kit-0.1.0/tests/providers/__init__.py +0 -0
  193. py_serverless_kit-0.1.0/tests/providers/test_alibaba.py +137 -0
  194. py_serverless_kit-0.1.0/tests/providers/test_aws.py +182 -0
  195. py_serverless_kit-0.1.0/tests/providers/test_azure.py +104 -0
  196. py_serverless_kit-0.1.0/tests/providers/test_cloudflare.py +110 -0
  197. py_serverless_kit-0.1.0/tests/providers/test_digitalocean.py +73 -0
  198. py_serverless_kit-0.1.0/tests/providers/test_gcp.py +212 -0
  199. py_serverless_kit-0.1.0/tests/providers/test_huawei.py +94 -0
  200. py_serverless_kit-0.1.0/tests/providers/test_ibm.py +66 -0
  201. py_serverless_kit-0.1.0/tests/providers/test_oracle.py +87 -0
  202. py_serverless_kit-0.1.0/tests/providers/test_schedule.py +59 -0
  203. py_serverless_kit-0.1.0/tests/providers/test_tencent.py +137 -0
  204. py_serverless_kit-0.1.0/tests/runtime/__init__.py +0 -0
  205. py_serverless_kit-0.1.0/tests/runtime/test_adapter_alibaba.py +142 -0
  206. py_serverless_kit-0.1.0/tests/runtime/test_adapter_aws.py +184 -0
  207. py_serverless_kit-0.1.0/tests/runtime/test_adapter_azure.py +146 -0
  208. py_serverless_kit-0.1.0/tests/runtime/test_adapter_cloudflare.py +84 -0
  209. py_serverless_kit-0.1.0/tests/runtime/test_adapter_digitalocean.py +82 -0
  210. py_serverless_kit-0.1.0/tests/runtime/test_adapter_gcp.py +165 -0
  211. py_serverless_kit-0.1.0/tests/runtime/test_adapter_huawei.py +146 -0
  212. py_serverless_kit-0.1.0/tests/runtime/test_adapter_ibm.py +105 -0
  213. py_serverless_kit-0.1.0/tests/runtime/test_adapter_oracle.py +85 -0
  214. py_serverless_kit-0.1.0/tests/runtime/test_adapter_tencent.py +134 -0
  215. py_serverless_kit-0.1.0/tests/runtime/test_dispatch.py +146 -0
  216. py_serverless_kit-0.1.0/tests/runtime/test_models.py +161 -0
  217. py_serverless_kit-0.1.0/tests/runtime/test_workflow_engine.py +174 -0
  218. py_serverless_kit-0.1.0/tests/test_cli.py +169 -0
  219. py_serverless_kit-0.1.0/tests/test_dashboard.py +37 -0
  220. py_serverless_kit-0.1.0/tests/test_examples.py +182 -0
  221. py_serverless_kit-0.1.0/tests/test_packaging.py +133 -0
  222. py_serverless_kit-0.1.0/tests/workflows/__init__.py +0 -0
  223. py_serverless_kit-0.1.0/tests/workflows/test_compilers.py +141 -0
@@ -0,0 +1,28 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .venv/
6
+ venv/
7
+ build/
8
+ dist/
9
+ .pytest_cache/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+ .coverage
13
+ htmlcov/
14
+ .pypirc
15
+ # py-serverless-kit working dirs (local terraform state, artifacts)
16
+ .pskit/
17
+ .terraform/
18
+ *.tfstate
19
+ *.tfstate.*
20
+
21
+ # Secrets
22
+ .env
23
+ .pypirc
24
+
25
+ # Editors / OS
26
+ .idea/
27
+ .vscode/
28
+ .DS_Store
@@ -0,0 +1,20 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented here. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project uses [Semantic Versioning](https://semver.org/).
4
+
5
+ > The function runtime is bundled into every deployment. After upgrading `py-serverless-kit`, run `pskit deploy` again to pick up runtime fixes.
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-10-15
10
+
11
+ ### Added
12
+ - Portable handler API: `Event`, `HttpRequest`, `Record`, `Headers`, `Context`, `Response`, HTTP error classes, `BatchResult`, `invoke()`.
13
+ - `pskit.yml` configuration with `extends:`, `providers:` and `stages:` overrides, and `${env:}`, `${opt:}`, `${self:}`, `${file()}` and `${tf:}` variables.
14
+ - Providers: AWS (stable), Google Cloud (stable), Azure (stable), Alibaba Cloud (beta), Huawei Cloud (beta), Tencent Cloud (beta), DigitalOcean (beta), IBM Cloud (beta), Oracle Cloud (experimental), Cloudflare Workers (experimental).
15
+ - Triggers: HTTP (path params, CORS, auth), schedule (rate/cron), queue, storage, topic.
16
+ - Workflows: native AWS Step Functions and Google Cloud Workflows compilers, plus an embedded engine for the other providers and local runs.
17
+ - CLI: `init`, `validate`, `package`, `plan`, `deploy`, `remove`, `info`, `dashboard`, `dev`, `invoke`, `workflow run|show`, `providers`, `tf`.
18
+ - Deployment dashboard (self-contained HTML).
19
+ - Local dev server with hot reload, and `LocalRunner` for tests.
20
+ - `scripts/validate_all_providers.py`, which runs `terraform validate` for every provider.
@@ -0,0 +1,13 @@
1
+ # Contributing
2
+
3
+ The full contributor guide lives in [deploy_docs/CONTRIBUTING.md](deploy_docs/CONTRIBUTING.md). It covers the project layout, dev setup, how to add providers and options, and how to verify Terraform.
4
+
5
+ Maintainers releasing to PyPI: see [deploy_docs/PUBLISHING_TO_PYPI.md](deploy_docs/PUBLISHING_TO_PYPI.md).
6
+
7
+ Quick start:
8
+
9
+ ```bash
10
+ python -m venv .venv && source .venv/bin/activate # Windows: .venv\Scripts\Activate.ps1
11
+ pip install -e ".[dev]"
12
+ pytest && ruff check src tests && mypy
13
+ ```
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Asif Khan @ Kavion.ai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,300 @@
1
+ Metadata-Version: 2.5
2
+ Name: py-serverless-kit
3
+ Version: 0.1.0
4
+ Summary: Write a Python serverless function once and deploy it to AWS, Azure, GCP and 7 more clouds with one YAML file, powered by Terraform.
5
+ Project-URL: Homepage, https://github.com/kavion-ai/py-serverless-kit
6
+ Project-URL: Documentation, https://github.com/kavion-ai/py-serverless-kit/tree/main/docs
7
+ Project-URL: Issues, https://github.com/kavion-ai/py-serverless-kit/issues
8
+ Project-URL: Changelog, https://github.com/kavion-ai/py-serverless-kit/blob/main/CHANGELOG.md
9
+ Author: Asif Khan @ Kavion.ai
10
+ Maintainer: Asif Khan @ Kavion.ai
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: aws,azure,faas,gcp,lambda,multi-cloud,serverless,step-functions,terraform
14
+ Classifier: Development Status :: 4 - Beta
15
+ Classifier: Environment :: Console
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: License :: OSI Approved :: MIT License
18
+ Classifier: Operating System :: OS Independent
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3 :: Only
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Topic :: Software Development :: Build Tools
27
+ Classifier: Topic :: System :: Distributed Computing
28
+ Classifier: Typing :: Typed
29
+ Requires-Python: >=3.9
30
+ Requires-Dist: click>=8.1
31
+ Requires-Dist: pydantic<3,>=2.5
32
+ Requires-Dist: pyyaml>=6.0
33
+ Provides-Extra: aws
34
+ Requires-Dist: boto3>=1.28; extra == 'aws'
35
+ Provides-Extra: dev
36
+ Requires-Dist: build>=1.0; extra == 'dev'
37
+ Requires-Dist: mypy>=1.8; extra == 'dev'
38
+ Requires-Dist: pytest-cov>=4.1; extra == 'dev'
39
+ Requires-Dist: pytest>=7.4; extra == 'dev'
40
+ Requires-Dist: ruff>=0.5; extra == 'dev'
41
+ Requires-Dist: twine>=5.0; extra == 'dev'
42
+ Requires-Dist: types-pyyaml; extra == 'dev'
43
+ Description-Content-Type: text/markdown
44
+
45
+ # py-serverless-kit
46
+
47
+ **Write your Python functions once. Deploy them to any of 10 clouds by changing one line of YAML.**
48
+
49
+ `py-serverless-kit` (CLI: `pskit`) is a Serverless-Framework-style toolkit built on **Terraform**. Your handlers use one small, provider-neutral API (`Event`, `Context`, `Response`). A `pskit.yml` file says which cloud they run on and what triggers them: HTTP, schedules, queues, storage, topics. The same file can also define workflows in the style of Step Functions. `pskit deploy` generates Terraform for the chosen cloud, applies it, and builds an HTML dashboard of everything you deployed.
50
+
51
+ ```python
52
+ # app/handlers.py - identical on AWS, Azure, GCP, Alibaba, Oracle, IBM, DigitalOcean, Tencent, Huawei, Cloudflare
53
+ from py_serverless_kit import Event, Context, NotFound
54
+
55
+ def get_order(event: Event, ctx: Context):
56
+ order = ORDERS.get(event.http.path_params["id"])
57
+ if order is None:
58
+ raise NotFound("no such order") # -> HTTP 404 JSON on every cloud
59
+ return order # -> HTTP 200 JSON
60
+ ```
61
+
62
+ ```yaml
63
+ # pskit.yml
64
+ service: orders
65
+ provider:
66
+ name: aws # <- change to gcp, azure, alibaba, ... and redeploy. That's the migration.
67
+ region: us-east-1
68
+ functions:
69
+ get-order:
70
+ handler: app.handlers.get_order
71
+ events:
72
+ - http: GET /orders/{id}
73
+ ```
74
+
75
+ ```bash
76
+ pskit deploy # terraform apply on AWS
77
+ pskit deploy --provider gcp # same code, Google Cloud Functions
78
+ pskit dashboard --open # every function, trigger, URL and resource id
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Why
84
+
85
+ Teams that build on AWS Lambda and Step Functions end up with code full of API Gateway event parsing, SQS record loops and hand-written ASL. When the business needs another cloud, every function has to be rewritten. `py-serverless-kit` fixes this at both layers:
86
+
87
+ | Layer | Locked-in way | With pskit |
88
+ |---|---|---|
89
+ | Handler code | Parses `event["requestContext"]["http"]["method"]`, `Records[].body`, ... | Uses `event.http.method`, `event.records[].body`: the same on every cloud |
90
+ | Triggers / infra | SAM / CloudFormation / console clicks | One `pskit.yml`, rendered to Terraform for the target cloud |
91
+ | Workflows | Step Functions ASL | Portable state machine, compiled to Step Functions, Google Cloud Workflows, or run by the built-in engine everywhere else |
92
+ | Visibility | One console per cloud | One generated dashboard across all clouds and stages |
93
+
94
+ ## Features
95
+
96
+ - **10 providers:** AWS Lambda, Azure Functions, Google Cloud Functions (gen2), Alibaba Function Compute, Oracle Functions, IBM Code Engine, DigitalOcean Functions, Tencent SCF, Huawei FunctionGraph, Cloudflare Workers.
97
+ - **Triggers:** HTTP (path params, CORS, auth), schedules (rate/cron, translated into each cloud's cron dialect), queues, object storage, pub/sub topics, and direct function-to-function `invoke()`.
98
+ - **Workflows:** task / choice / wait / pass / parallel / map / succeed / fail with retry and catch. Native on AWS and GCP; an embedded engine on the other clouds; runnable locally with `pskit workflow run`.
99
+ - **Terraform underneath:** real, reviewable `main.tf.json`, any backend (S3, GCS, azurerm, ...), works with OpenTofu. Escape hatches: `terraform.extra`, `${tf:...}` references, per-function `options`.
100
+ - **Config that scales:** `extends:`, per-provider `providers:` blocks, per-stage `stages:` blocks, and `${env:}`, `${opt:}`, `${self:}`, `${file()}` variables.
101
+ - **Local dev:** `pskit dev` (hot-reloading HTTP server), `pskit invoke` with synthetic queue/storage/schedule events, and a `LocalRunner` for pytest.
102
+ - **Dashboard:** a self-contained `index.html` listing every deployment, function, trigger, endpoint, ARN/id, console link and workflow.
103
+ - **Production details:** deterministic artifacts (no redeploy when nothing changed), partial batch failures (`BatchResult`), structured JSON logs, consistent HTTP error mapping, stack traces hidden from clients, a stdlib-only runtime (no extra dependencies inside your function), and hooks (`before_deploy`, ...).
104
+
105
+ ## Supported providers
106
+
107
+ | Provider | Tier | HTTP | Schedule | Queue | Storage | Topic | Workflows |
108
+ |---|---|:-:|:-:|:-:|:-:|:-:|---|
109
+ | AWS Lambda | stable | ✅ | ✅ | ✅ SQS | ✅ S3 | ✅ SNS | native (Step Functions) |
110
+ | Google Cloud Functions | stable | ✅ | ✅ | ✅ Pub/Sub | ✅ GCS | ✅ Pub/Sub | native (Cloud Workflows) |
111
+ | Azure Functions | stable | ✅ | ✅ | ✅ Storage Queue | ✅ Blob | ✅ Service Bus | embedded |
112
+ | Alibaba Function Compute | beta | ✅ | ✅ | – | ✅ OSS | ✅ MNS | embedded |
113
+ | Huawei FunctionGraph | beta | ✅ | ✅ | – | ✅ OBS | ✅ SMN | embedded |
114
+ | Tencent SCF | beta | ✅ | ✅ | – | ✅ COS | – | embedded |
115
+ | DigitalOcean Functions | beta | ✅ | ✅ | – | – | – | embedded |
116
+ | IBM Code Engine | beta | ✅ | – | – | – | – | embedded |
117
+ | Oracle Cloud Functions | experimental | ✅ | – | – | ✅ | – | embedded |
118
+ | Cloudflare Workers (Python) | experimental | ✅ | ✅ | – | – | – | embedded |
119
+
120
+ Run `pskit providers` for the live matrix. If a config uses a trigger the target cloud can't support, **`pskit validate` fails with a clear message instead of deploying something half-working.**
121
+
122
+ > **Maturity, honestly stated:** the Terraform generated for every provider is checked with `terraform validate` against the real provider plugins (in CI, too). The *stable* providers cover the most surface area. *beta* and *experimental* providers follow vendor docs for event payloads that `validate` can't check, so try them on a non-production account first. See [docs/providers.md](docs/providers.md) for each provider's details and limits.
123
+
124
+ ## Install
125
+
126
+ ```bash
127
+ pip install py-serverless-kit
128
+ ```
129
+
130
+ You also need **Terraform ≥ 1.5** (or OpenTofu) on your `PATH`, plus credentials for your cloud. See [Getting started](docs/getting-started.md#cloud-credentials).
131
+
132
+ ## Quick start
133
+
134
+ ```bash
135
+ pskit init my-api --provider aws --template full # templates: http | events | workflow | full
136
+ cd my-api
137
+ pskit dev # http://127.0.0.1:3000/hello
138
+ pskit invoke -f hello --path "/hello?name=Ada"
139
+ pskit workflow run order-pipeline -i '{"amount": 42}'
140
+ pskit deploy --stage dev
141
+ pskit info
142
+ pskit dashboard --open
143
+ pskit remove --stage dev
144
+ ```
145
+
146
+ ### Move to another cloud
147
+
148
+ Change `provider.name`, or keep one file with per-cloud blocks:
149
+
150
+ ```yaml
151
+ provider:
152
+ name: aws
153
+ region: us-east-1
154
+ providers: # applied only when that provider is selected
155
+ gcp: {region: europe-west1, options: {project: my-project}}
156
+ azure: {region: westeurope, options: {subscription_id: "${env:ARM_SUBSCRIPTION_ID}"}}
157
+ ```
158
+
159
+ ```bash
160
+ pskit deploy --provider gcp
161
+ pskit deploy --provider azure --stage prod
162
+ ```
163
+
164
+ ### Triggers at a glance
165
+
166
+ ```yaml
167
+ functions:
168
+ api:
169
+ handler: app.api.handle
170
+ events:
171
+ - http: {method: POST, path: /orders, cors: true}
172
+ - http: GET /orders/{id}
173
+ nightly:
174
+ handler: app.jobs.nightly
175
+ events:
176
+ - schedule: {cron: "0 2 * * *", input: {report: daily}, timezone: Europe/Berlin}
177
+ worker:
178
+ handler: app.jobs.process
179
+ timeout: 60
180
+ events:
181
+ - queue: {name: orders, batch_size: 10, dead_letter: orders-dlq}
182
+ thumbnails:
183
+ handler: app.media.on_upload
184
+ events:
185
+ - storage: {bucket: my-uploads-bucket, events: [created], suffix: .jpg}
186
+ audit:
187
+ handler: app.audit.on_event
188
+ events:
189
+ - topic: order-events
190
+ ```
191
+
192
+ ```python
193
+ from py_serverless_kit import BatchResult, Event, Context
194
+
195
+ def process(event: Event, ctx: Context):
196
+ result = BatchResult() # retry only failed messages where the cloud supports it
197
+ for record in event.records:
198
+ try:
199
+ handle(record.json())
200
+ except Exception:
201
+ result.fail(record)
202
+ return result
203
+ ```
204
+
205
+ ### Workflows (portable Step Functions)
206
+
207
+ ```yaml
208
+ workflows:
209
+ order-pipeline:
210
+ start_at: Validate
211
+ states:
212
+ Validate:
213
+ type: task
214
+ function: validate-order
215
+ retry: [{errors: [TimeoutError], max_attempts: 3, backoff_rate: 2}]
216
+ catch: [{errors: [ValueError], next: Rejected}]
217
+ next: Route
218
+ Route:
219
+ type: choice
220
+ choices: [{variable: "$.amount", gt: 1000, next: ManualReview}]
221
+ default: Charge
222
+ ManualReview: {type: wait, seconds: 3600, next: Charge}
223
+ Charge: {type: task, function: charge-order, end: true}
224
+ Rejected: {type: fail, error: OrderRejected}
225
+ ```
226
+
227
+ The same definition becomes **AWS Step Functions** on AWS, **Google Cloud Workflows** on GCP, and an **embedded orchestrator function** on the other clouds. `pskit workflow show order-pipeline --format asl` prints the generated ASL.
228
+
229
+ ## How it works
230
+
231
+ ```
232
+ pskit.yml ──► config loader ──► provider validation ──► packager ──────────► artifact.zip
233
+ (extends, providers:, (capabilities, (your code + stdlib-only
234
+ stages:, ${vars}) limits, runtimes) runtime + manifest + shim)
235
+ │
236
+ ▼
237
+ provider renderer ──► .pskit/<provider>-<stage>/main.tf.json
238
+ │ terraform init / apply
239
+ ▼
240
+ deployment.json ──► dashboard/index.html
241
+
242
+ At runtime: cloud event ──► shim ──► runtime.adapters.<cloud> ──► Event ──► your handler
243
+ your result ──► Response / raw value ──► adapter ──► native cloud response
244
+ ```
245
+
246
+ More: [docs/architecture.md](docs/architecture.md).
247
+
248
+ ## Examples
249
+
250
+ Fifteen runnable scenarios live in [`examples/`](examples/). They are tested in CI.
251
+
252
+ | | |
253
+ |---|---|
254
+ | [01-hello-http](examples/01-hello-http) | Minimal HTTP function |
255
+ | [02-rest-api](examples/02-rest-api) | CRUD, path params, validation errors, CORS, cookies, binary, JWT |
256
+ | [03-scheduled-jobs](examples/03-scheduled-jobs) | rate/cron schedules with input and time zones |
257
+ | [04-queue-worker](examples/04-queue-worker) | Queue consumer, partial batch failures, dead-letter queue |
258
+ | [05-storage-events](examples/05-storage-events) | Object created/deleted with filters |
259
+ | [06-pubsub-topic](examples/06-pubsub-topic) | Topic fan-out and filters |
260
+ | [07-workflow-orders](examples/07-workflow-orders) | Every workflow state type, retry/catch |
261
+ | [08-multi-cloud](examples/08-multi-cloud) | Same code, all 10 providers |
262
+ | [09-function-invoke](examples/09-function-invoke) | Function-to-function `invoke()` |
263
+ | [10-stages-and-config](examples/10-stages-and-config) | Stages, variables, secrets |
264
+ | [11-custom-terraform](examples/11-custom-terraform) | `terraform.extra`, `${tf:...}`, remote state, hooks |
265
+ | [12-async-and-context](examples/12-async-and-context) | async handlers, logging, deadlines |
266
+ | [13-migrate-from-aws-lambda](examples/13-migrate-from-aws-lambda) | Before/after migration of Lambda + Step Functions |
267
+ | [14-testing](examples/14-testing) | Unit-testing handlers and workflows with pytest |
268
+ | [15-ci-cd-deploy](examples/15-ci-cd-deploy) | GitHub Actions deploys per stage |
269
+
270
+ ## Documentation
271
+
272
+ | | |
273
+ |---|---|
274
+ | [Getting started](docs/getting-started.md) | Install, credentials, first deploy |
275
+ | [Configuration reference](docs/configuration.md) | Every `pskit.yml` key, variables, `extends`, stages |
276
+ | [Events](docs/events.md) | HTTP, schedule, queue, storage, topic, with a per-provider matrix |
277
+ | [Handler API](docs/handlers.md) | `Event`, `Context`, `Response`, errors, `BatchResult`, `invoke()` |
278
+ | [Workflows](docs/workflows.md) | State machine reference, engines, limitations |
279
+ | [Providers](docs/providers.md) | Options, credentials, resources and limits per cloud |
280
+ | [CLI](docs/cli.md) | Every command and flag |
281
+ | [Local development](docs/local-development.md) | `pskit dev`, `invoke`, testing |
282
+ | [Dashboard](docs/dashboard.md) | The deployment UI |
283
+ | [Architecture](docs/architecture.md) | Internals and third-party providers |
284
+ | [Migrating from AWS](docs/migrating-from-aws.md) | Lambda + Step Functions → pskit |
285
+ | [Troubleshooting](docs/troubleshooting.md) | Common errors and fixes |
286
+
287
+ ## Contributing & releasing
288
+
289
+ - Contributor guide: [deploy_docs/CONTRIBUTING.md](deploy_docs/CONTRIBUTING.md)
290
+ - Quick PyPI release guide: [deploy_docs/How_to_deploy.md](deploy_docs/How_to_deploy.md)
291
+ - Publishing to PyPI (step by step): [deploy_docs/PUBLISHING_TO_PYPI.md](deploy_docs/PUBLISHING_TO_PYPI.md)
292
+ - Security policy: [SECURITY.md](SECURITY.md)
293
+
294
+ ## Author
295
+
296
+ Created and maintained by **Asif Khan @ [Kavion.ai](https://kavion.ai)**.
297
+
298
+ ## License
299
+
300
+ MIT, see [LICENSE](LICENSE).
@@ -0,0 +1,256 @@
1
+ # py-serverless-kit
2
+
3
+ **Write your Python functions once. Deploy them to any of 10 clouds by changing one line of YAML.**
4
+
5
+ `py-serverless-kit` (CLI: `pskit`) is a Serverless-Framework-style toolkit built on **Terraform**. Your handlers use one small, provider-neutral API (`Event`, `Context`, `Response`). A `pskit.yml` file says which cloud they run on and what triggers them: HTTP, schedules, queues, storage, topics. The same file can also define workflows in the style of Step Functions. `pskit deploy` generates Terraform for the chosen cloud, applies it, and builds an HTML dashboard of everything you deployed.
6
+
7
+ ```python
8
+ # app/handlers.py - identical on AWS, Azure, GCP, Alibaba, Oracle, IBM, DigitalOcean, Tencent, Huawei, Cloudflare
9
+ from py_serverless_kit import Event, Context, NotFound
10
+
11
+ def get_order(event: Event, ctx: Context):
12
+ order = ORDERS.get(event.http.path_params["id"])
13
+ if order is None:
14
+ raise NotFound("no such order") # -> HTTP 404 JSON on every cloud
15
+ return order # -> HTTP 200 JSON
16
+ ```
17
+
18
+ ```yaml
19
+ # pskit.yml
20
+ service: orders
21
+ provider:
22
+ name: aws # <- change to gcp, azure, alibaba, ... and redeploy. That's the migration.
23
+ region: us-east-1
24
+ functions:
25
+ get-order:
26
+ handler: app.handlers.get_order
27
+ events:
28
+ - http: GET /orders/{id}
29
+ ```
30
+
31
+ ```bash
32
+ pskit deploy # terraform apply on AWS
33
+ pskit deploy --provider gcp # same code, Google Cloud Functions
34
+ pskit dashboard --open # every function, trigger, URL and resource id
35
+ ```
36
+
37
+ ---
38
+
39
+ ## Why
40
+
41
+ Teams that build on AWS Lambda and Step Functions end up with code full of API Gateway event parsing, SQS record loops and hand-written ASL. When the business needs another cloud, every function has to be rewritten. `py-serverless-kit` fixes this at both layers:
42
+
43
+ | Layer | Locked-in way | With pskit |
44
+ |---|---|---|
45
+ | Handler code | Parses `event["requestContext"]["http"]["method"]`, `Records[].body`, ... | Uses `event.http.method`, `event.records[].body`: the same on every cloud |
46
+ | Triggers / infra | SAM / CloudFormation / console clicks | One `pskit.yml`, rendered to Terraform for the target cloud |
47
+ | Workflows | Step Functions ASL | Portable state machine, compiled to Step Functions, Google Cloud Workflows, or run by the built-in engine everywhere else |
48
+ | Visibility | One console per cloud | One generated dashboard across all clouds and stages |
49
+
50
+ ## Features
51
+
52
+ - **10 providers:** AWS Lambda, Azure Functions, Google Cloud Functions (gen2), Alibaba Function Compute, Oracle Functions, IBM Code Engine, DigitalOcean Functions, Tencent SCF, Huawei FunctionGraph, Cloudflare Workers.
53
+ - **Triggers:** HTTP (path params, CORS, auth), schedules (rate/cron, translated into each cloud's cron dialect), queues, object storage, pub/sub topics, and direct function-to-function `invoke()`.
54
+ - **Workflows:** task / choice / wait / pass / parallel / map / succeed / fail with retry and catch. Native on AWS and GCP; an embedded engine on the other clouds; runnable locally with `pskit workflow run`.
55
+ - **Terraform underneath:** real, reviewable `main.tf.json`, any backend (S3, GCS, azurerm, ...), works with OpenTofu. Escape hatches: `terraform.extra`, `${tf:...}` references, per-function `options`.
56
+ - **Config that scales:** `extends:`, per-provider `providers:` blocks, per-stage `stages:` blocks, and `${env:}`, `${opt:}`, `${self:}`, `${file()}` variables.
57
+ - **Local dev:** `pskit dev` (hot-reloading HTTP server), `pskit invoke` with synthetic queue/storage/schedule events, and a `LocalRunner` for pytest.
58
+ - **Dashboard:** a self-contained `index.html` listing every deployment, function, trigger, endpoint, ARN/id, console link and workflow.
59
+ - **Production details:** deterministic artifacts (no redeploy when nothing changed), partial batch failures (`BatchResult`), structured JSON logs, consistent HTTP error mapping, stack traces hidden from clients, a stdlib-only runtime (no extra dependencies inside your function), and hooks (`before_deploy`, ...).
60
+
61
+ ## Supported providers
62
+
63
+ | Provider | Tier | HTTP | Schedule | Queue | Storage | Topic | Workflows |
64
+ |---|---|:-:|:-:|:-:|:-:|:-:|---|
65
+ | AWS Lambda | stable | ✅ | ✅ | ✅ SQS | ✅ S3 | ✅ SNS | native (Step Functions) |
66
+ | Google Cloud Functions | stable | ✅ | ✅ | ✅ Pub/Sub | ✅ GCS | ✅ Pub/Sub | native (Cloud Workflows) |
67
+ | Azure Functions | stable | ✅ | ✅ | ✅ Storage Queue | ✅ Blob | ✅ Service Bus | embedded |
68
+ | Alibaba Function Compute | beta | ✅ | ✅ | – | ✅ OSS | ✅ MNS | embedded |
69
+ | Huawei FunctionGraph | beta | ✅ | ✅ | – | ✅ OBS | ✅ SMN | embedded |
70
+ | Tencent SCF | beta | ✅ | ✅ | – | ✅ COS | – | embedded |
71
+ | DigitalOcean Functions | beta | ✅ | ✅ | – | – | – | embedded |
72
+ | IBM Code Engine | beta | ✅ | – | – | – | – | embedded |
73
+ | Oracle Cloud Functions | experimental | ✅ | – | – | ✅ | – | embedded |
74
+ | Cloudflare Workers (Python) | experimental | ✅ | ✅ | – | – | – | embedded |
75
+
76
+ Run `pskit providers` for the live matrix. If a config uses a trigger the target cloud can't support, **`pskit validate` fails with a clear message instead of deploying something half-working.**
77
+
78
+ > **Maturity, honestly stated:** the Terraform generated for every provider is checked with `terraform validate` against the real provider plugins (in CI, too). The *stable* providers cover the most surface area. *beta* and *experimental* providers follow vendor docs for event payloads that `validate` can't check, so try them on a non-production account first. See [docs/providers.md](docs/providers.md) for each provider's details and limits.
79
+
80
+ ## Install
81
+
82
+ ```bash
83
+ pip install py-serverless-kit
84
+ ```
85
+
86
+ You also need **Terraform ≥ 1.5** (or OpenTofu) on your `PATH`, plus credentials for your cloud. See [Getting started](docs/getting-started.md#cloud-credentials).
87
+
88
+ ## Quick start
89
+
90
+ ```bash
91
+ pskit init my-api --provider aws --template full # templates: http | events | workflow | full
92
+ cd my-api
93
+ pskit dev # http://127.0.0.1:3000/hello
94
+ pskit invoke -f hello --path "/hello?name=Ada"
95
+ pskit workflow run order-pipeline -i '{"amount": 42}'
96
+ pskit deploy --stage dev
97
+ pskit info
98
+ pskit dashboard --open
99
+ pskit remove --stage dev
100
+ ```
101
+
102
+ ### Move to another cloud
103
+
104
+ Change `provider.name`, or keep one file with per-cloud blocks:
105
+
106
+ ```yaml
107
+ provider:
108
+ name: aws
109
+ region: us-east-1
110
+ providers: # applied only when that provider is selected
111
+ gcp: {region: europe-west1, options: {project: my-project}}
112
+ azure: {region: westeurope, options: {subscription_id: "${env:ARM_SUBSCRIPTION_ID}"}}
113
+ ```
114
+
115
+ ```bash
116
+ pskit deploy --provider gcp
117
+ pskit deploy --provider azure --stage prod
118
+ ```
119
+
120
+ ### Triggers at a glance
121
+
122
+ ```yaml
123
+ functions:
124
+ api:
125
+ handler: app.api.handle
126
+ events:
127
+ - http: {method: POST, path: /orders, cors: true}
128
+ - http: GET /orders/{id}
129
+ nightly:
130
+ handler: app.jobs.nightly
131
+ events:
132
+ - schedule: {cron: "0 2 * * *", input: {report: daily}, timezone: Europe/Berlin}
133
+ worker:
134
+ handler: app.jobs.process
135
+ timeout: 60
136
+ events:
137
+ - queue: {name: orders, batch_size: 10, dead_letter: orders-dlq}
138
+ thumbnails:
139
+ handler: app.media.on_upload
140
+ events:
141
+ - storage: {bucket: my-uploads-bucket, events: [created], suffix: .jpg}
142
+ audit:
143
+ handler: app.audit.on_event
144
+ events:
145
+ - topic: order-events
146
+ ```
147
+
148
+ ```python
149
+ from py_serverless_kit import BatchResult, Event, Context
150
+
151
+ def process(event: Event, ctx: Context):
152
+ result = BatchResult() # retry only failed messages where the cloud supports it
153
+ for record in event.records:
154
+ try:
155
+ handle(record.json())
156
+ except Exception:
157
+ result.fail(record)
158
+ return result
159
+ ```
160
+
161
+ ### Workflows (portable Step Functions)
162
+
163
+ ```yaml
164
+ workflows:
165
+ order-pipeline:
166
+ start_at: Validate
167
+ states:
168
+ Validate:
169
+ type: task
170
+ function: validate-order
171
+ retry: [{errors: [TimeoutError], max_attempts: 3, backoff_rate: 2}]
172
+ catch: [{errors: [ValueError], next: Rejected}]
173
+ next: Route
174
+ Route:
175
+ type: choice
176
+ choices: [{variable: "$.amount", gt: 1000, next: ManualReview}]
177
+ default: Charge
178
+ ManualReview: {type: wait, seconds: 3600, next: Charge}
179
+ Charge: {type: task, function: charge-order, end: true}
180
+ Rejected: {type: fail, error: OrderRejected}
181
+ ```
182
+
183
+ The same definition becomes **AWS Step Functions** on AWS, **Google Cloud Workflows** on GCP, and an **embedded orchestrator function** on the other clouds. `pskit workflow show order-pipeline --format asl` prints the generated ASL.
184
+
185
+ ## How it works
186
+
187
+ ```
188
+ pskit.yml ──► config loader ──► provider validation ──► packager ──────────► artifact.zip
189
+ (extends, providers:, (capabilities, (your code + stdlib-only
190
+ stages:, ${vars}) limits, runtimes) runtime + manifest + shim)
191
+ │
192
+ ▼
193
+ provider renderer ──► .pskit/<provider>-<stage>/main.tf.json
194
+ │ terraform init / apply
195
+ ▼
196
+ deployment.json ──► dashboard/index.html
197
+
198
+ At runtime: cloud event ──► shim ──► runtime.adapters.<cloud> ──► Event ──► your handler
199
+ your result ──► Response / raw value ──► adapter ──► native cloud response
200
+ ```
201
+
202
+ More: [docs/architecture.md](docs/architecture.md).
203
+
204
+ ## Examples
205
+
206
+ Fifteen runnable scenarios live in [`examples/`](examples/). They are tested in CI.
207
+
208
+ | | |
209
+ |---|---|
210
+ | [01-hello-http](examples/01-hello-http) | Minimal HTTP function |
211
+ | [02-rest-api](examples/02-rest-api) | CRUD, path params, validation errors, CORS, cookies, binary, JWT |
212
+ | [03-scheduled-jobs](examples/03-scheduled-jobs) | rate/cron schedules with input and time zones |
213
+ | [04-queue-worker](examples/04-queue-worker) | Queue consumer, partial batch failures, dead-letter queue |
214
+ | [05-storage-events](examples/05-storage-events) | Object created/deleted with filters |
215
+ | [06-pubsub-topic](examples/06-pubsub-topic) | Topic fan-out and filters |
216
+ | [07-workflow-orders](examples/07-workflow-orders) | Every workflow state type, retry/catch |
217
+ | [08-multi-cloud](examples/08-multi-cloud) | Same code, all 10 providers |
218
+ | [09-function-invoke](examples/09-function-invoke) | Function-to-function `invoke()` |
219
+ | [10-stages-and-config](examples/10-stages-and-config) | Stages, variables, secrets |
220
+ | [11-custom-terraform](examples/11-custom-terraform) | `terraform.extra`, `${tf:...}`, remote state, hooks |
221
+ | [12-async-and-context](examples/12-async-and-context) | async handlers, logging, deadlines |
222
+ | [13-migrate-from-aws-lambda](examples/13-migrate-from-aws-lambda) | Before/after migration of Lambda + Step Functions |
223
+ | [14-testing](examples/14-testing) | Unit-testing handlers and workflows with pytest |
224
+ | [15-ci-cd-deploy](examples/15-ci-cd-deploy) | GitHub Actions deploys per stage |
225
+
226
+ ## Documentation
227
+
228
+ | | |
229
+ |---|---|
230
+ | [Getting started](docs/getting-started.md) | Install, credentials, first deploy |
231
+ | [Configuration reference](docs/configuration.md) | Every `pskit.yml` key, variables, `extends`, stages |
232
+ | [Events](docs/events.md) | HTTP, schedule, queue, storage, topic, with a per-provider matrix |
233
+ | [Handler API](docs/handlers.md) | `Event`, `Context`, `Response`, errors, `BatchResult`, `invoke()` |
234
+ | [Workflows](docs/workflows.md) | State machine reference, engines, limitations |
235
+ | [Providers](docs/providers.md) | Options, credentials, resources and limits per cloud |
236
+ | [CLI](docs/cli.md) | Every command and flag |
237
+ | [Local development](docs/local-development.md) | `pskit dev`, `invoke`, testing |
238
+ | [Dashboard](docs/dashboard.md) | The deployment UI |
239
+ | [Architecture](docs/architecture.md) | Internals and third-party providers |
240
+ | [Migrating from AWS](docs/migrating-from-aws.md) | Lambda + Step Functions → pskit |
241
+ | [Troubleshooting](docs/troubleshooting.md) | Common errors and fixes |
242
+
243
+ ## Contributing & releasing
244
+
245
+ - Contributor guide: [deploy_docs/CONTRIBUTING.md](deploy_docs/CONTRIBUTING.md)
246
+ - Quick PyPI release guide: [deploy_docs/How_to_deploy.md](deploy_docs/How_to_deploy.md)
247
+ - Publishing to PyPI (step by step): [deploy_docs/PUBLISHING_TO_PYPI.md](deploy_docs/PUBLISHING_TO_PYPI.md)
248
+ - Security policy: [SECURITY.md](SECURITY.md)
249
+
250
+ ## Author
251
+
252
+ Created and maintained by **Asif Khan @ [Kavion.ai](https://kavion.ai)**.
253
+
254
+ ## License
255
+
256
+ MIT, see [LICENSE](LICENSE).