py-serverless-kit 0.2.0__tar.gz → 0.3.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.
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/CHANGELOG.md +11 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/PKG-INFO +3 -3
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/README.md +2 -2
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/architecture.md +3 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/configuration.md +1 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/getting-started.md +1 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/local-development.md +1 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/providers.md +47 -9
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/troubleshooting.md +1 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/16-on-premises/README.md +3 -0
- py_serverless_kit-0.3.0/examples/17-on-premises-remote/README.md +97 -0
- py_serverless_kit-0.3.0/examples/17-on-premises-remote/app/__init__.py +1 -0
- py_serverless_kit-0.3.0/examples/17-on-premises-remote/app/handlers.py +16 -0
- py_serverless_kit-0.3.0/examples/17-on-premises-remote/pskit.yml +60 -0
- py_serverless_kit-0.3.0/examples/17-on-premises-remote/requirements.txt +1 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/README.md +1 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/_version.py +1 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/cli/templates.py +3 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/packaging/builder.py +1 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/base.py +3 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/onprem.py +183 -57
- py_serverless_kit-0.3.0/src/py_serverless_kit/providers/onprem_remote.py +381 -0
- py_serverless_kit-0.3.0/src/py_serverless_kit/providers/onprem_spec.py +404 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/onprem_host.py +3 -3
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_onprem.py +129 -2
- py_serverless_kit-0.3.0/tests/providers/test_onprem_remote.py +148 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/test_examples.py +2 -1
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/.gitignore +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/CONTRIBUTING.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/LICENSE +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/deploy_docs/CONTRIBUTING.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/cli.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/dashboard.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/events.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/handlers.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/migrating-from-aws.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/docs/workflows.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/01-hello-http/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/01-hello-http/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/01-hello-http/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/01-hello-http/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/01-hello-http/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/02-rest-api/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/02-rest-api/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/02-rest-api/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/02-rest-api/app/store.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/02-rest-api/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/02-rest-api/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/03-scheduled-jobs/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/03-scheduled-jobs/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/03-scheduled-jobs/app/jobs.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/03-scheduled-jobs/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/03-scheduled-jobs/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/04-queue-worker/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/04-queue-worker/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/04-queue-worker/app/worker.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/04-queue-worker/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/04-queue-worker/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/05-storage-events/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/05-storage-events/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/05-storage-events/app/files.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/05-storage-events/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/05-storage-events/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/06-pubsub-topic/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/06-pubsub-topic/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/06-pubsub-topic/app/subscribers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/06-pubsub-topic/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/06-pubsub-topic/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/app/orders.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/events/b2b.json +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/events/declined.json +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/events/happy.json +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/07-workflow-orders/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/pskit.aws.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/pskit.azure.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/pskit.gcp.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/08-multi-cloud/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/09-function-invoke/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/09-function-invoke/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/09-function-invoke/app/quotes.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/09-function-invoke/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/09-function-invoke/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/.env.example +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/app/settings.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/config/limits.json +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/10-stages-and-config/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/app/repository.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/scripts/smoke_test.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/11-custom-terraform/tests/test_orders.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/12-async-and-context/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/12-async-and-context/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/12-async-and-context/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/12-async-and-context/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/12-async-and-context/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/after/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/after/app/orders.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/after/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/after/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/before/lambda_function.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/before/state_machine.asl.json +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/13-migrate-from-aws-lambda/before/template.yaml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/ci.github-workflow.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/tests/conftest.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/tests/test_handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/14-testing/tests/test_workflow.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/15-ci-cd-deploy/README.md +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/15-ci-cd-deploy/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/15-ci-cd-deploy/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/15-ci-cd-deploy/deploy.github-workflow.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/15-ci-cd-deploy/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/15-ci-cd-deploy/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/16-on-premises/app/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/16-on-premises/app/handlers.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/16-on-premises/pskit.yml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/examples/16-on-premises/requirements.txt +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/pyproject.toml +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/__main__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/cli/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/cli/main.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/config/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/config/loader.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/config/schema.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/core/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/core/deployer.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/core/describe.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/core/project.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/dashboard/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/dashboard/generator.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/dashboard/template.html +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/local/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/local/runner.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/local/server.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/packaging/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/alibaba.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/aws.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/azure.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/cloudflare.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/digitalocean.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/gcp.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/huawei.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/ibm.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/oracle.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/registry.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/schedule.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/tencent.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/providers/terraform_doc.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/_httpfn.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/alibaba.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/aws.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/azure.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/base.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/cloudflare.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/digitalocean.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/gcp.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/huawei.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/ibm.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/onprem.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/oracle.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/adapters/tencent.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/batch.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/context.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/cron.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/dispatch.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/errors.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/event.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/invoke.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/log.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/manifest.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/response.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/routing.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/runtime/workflow.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/terraform/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/terraform/runner.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/workflows/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/workflows/asl.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/workflows/gcp.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/config/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/config/test_loader.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/config/test_schema.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/conftest.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/local/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/local/test_server.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_alibaba.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_aws.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_azure.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_cloudflare.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_digitalocean.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_gcp.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_huawei.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_ibm.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_oracle.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_schedule.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/providers/test_tencent.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_alibaba.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_aws.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_azure.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_cloudflare.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_digitalocean.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_gcp.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_huawei.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_ibm.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_onprem.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_oracle.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_adapter_tencent.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_cron.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_dispatch.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_models.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_onprem_host.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/runtime/test_workflow_engine.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/test_cli.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/test_dashboard.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/test_packaging.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/workflows/__init__.py +0 -0
- {py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/tests/workflows/test_compilers.py +0 -0
|
@@ -6,6 +6,17 @@ All notable changes to this project are documented here. The format follows [Kee
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.3.0] - 2026-10-17
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
- On-premises deploy targets. `provider.options.deploy.method` is `local` (default, previous behaviour), `ssh` (copy the host over OpenSSH and start a process or systemd unit), or `docker` (build an image that already contains Python). When the server has no Python, set `python: bundle` to ship a portable CPython, or use `method: docker`. `python_home` / `python_url` cover air-gapped mirrors. Wheels are vendored for the target OS/arch (manylinux when the server is Linux).
|
|
13
|
+
- Example [17-on-premises-remote](examples/17-on-premises-remote): SSH + bundled interpreter + systemd.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
- On-prem host: Windows process helpers (`ctypes.windll`, `subprocess.DETACHED_PROCESS`) are gated on `sys.platform == "win32"` so mypy on Linux/macOS CI no longer reports missing attributes.
|
|
17
|
+
|
|
18
|
+
Redeploy on-premises hosts to pick up the new `onprem_deploy.py` provisioner. Handler code is unchanged.
|
|
19
|
+
|
|
9
20
|
## [0.2.0] - 2026-10-17
|
|
10
21
|
|
|
11
22
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: py-serverless-kit
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Write a Python serverless function once and deploy it to AWS, Azure, GCP, 7 more clouds, or an on-premises host with one YAML file, powered by Terraform.
|
|
5
5
|
Project-URL: Homepage, https://github.com/ak9347128658/serverless_kit
|
|
6
6
|
Project-URL: Documentation, https://github.com/ak9347128658/serverless_kit/tree/main/docs
|
|
@@ -97,7 +97,7 @@ Teams that build on AWS Lambda and Step Functions end up with code full of API G
|
|
|
97
97
|
|
|
98
98
|
## Features
|
|
99
99
|
|
|
100
|
-
- **10 clouds and an on-premises host:** AWS Lambda, Azure Functions, Google Cloud Functions (gen2), Alibaba Function Compute, Oracle Functions, IBM Code Engine, DigitalOcean Functions, Tencent SCF, Huawei FunctionGraph, Cloudflare Workers, plus a process on your own machine (`onprem
|
|
100
|
+
- **10 clouds and an on-premises host:** AWS Lambda, Azure Functions, Google Cloud Functions (gen2), Alibaba Function Compute, Oracle Functions, IBM Code Engine, DigitalOcean Functions, Tencent SCF, Huawei FunctionGraph, Cloudflare Workers, plus a process on your own machine or a remote server (`onprem`: local, SSH, Docker, or a bundled CPython when the server has no Python).
|
|
101
101
|
- **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()`.
|
|
102
102
|
- **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`.
|
|
103
103
|
- **Terraform underneath:** real, reviewable `main.tf.json`, any backend (S3, GCS, azurerm, ...), works with OpenTofu. Escape hatches: `terraform.extra`, `${tf:...}` references, per-function `options`.
|
|
@@ -120,7 +120,7 @@ Teams that build on AWS Lambda and Step Functions end up with code full of API G
|
|
|
120
120
|
| IBM Code Engine | beta | ✅ | – | – | – | – | embedded |
|
|
121
121
|
| Oracle Cloud Functions | experimental | ✅ | – | – | ✅ | – | embedded |
|
|
122
122
|
| Cloudflare Workers (Python) | experimental | ✅ | ✅ | – | – | – | embedded |
|
|
123
|
-
| On-premises | experimental | ✅ | ✅ | ✅ files | ✅ directory | ✅ files | embedded (
|
|
123
|
+
| On-premises | experimental | ✅ | ✅ | ✅ files | ✅ directory | ✅ files | embedded (local, SSH, or Docker) |
|
|
124
124
|
|
|
125
125
|
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.**
|
|
126
126
|
|
|
@@ -53,7 +53,7 @@ Teams that build on AWS Lambda and Step Functions end up with code full of API G
|
|
|
53
53
|
|
|
54
54
|
## Features
|
|
55
55
|
|
|
56
|
-
- **10 clouds and an on-premises host:** AWS Lambda, Azure Functions, Google Cloud Functions (gen2), Alibaba Function Compute, Oracle Functions, IBM Code Engine, DigitalOcean Functions, Tencent SCF, Huawei FunctionGraph, Cloudflare Workers, plus a process on your own machine (`onprem
|
|
56
|
+
- **10 clouds and an on-premises host:** AWS Lambda, Azure Functions, Google Cloud Functions (gen2), Alibaba Function Compute, Oracle Functions, IBM Code Engine, DigitalOcean Functions, Tencent SCF, Huawei FunctionGraph, Cloudflare Workers, plus a process on your own machine or a remote server (`onprem`: local, SSH, Docker, or a bundled CPython when the server has no Python).
|
|
57
57
|
- **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()`.
|
|
58
58
|
- **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`.
|
|
59
59
|
- **Terraform underneath:** real, reviewable `main.tf.json`, any backend (S3, GCS, azurerm, ...), works with OpenTofu. Escape hatches: `terraform.extra`, `${tf:...}` references, per-function `options`.
|
|
@@ -76,7 +76,7 @@ Teams that build on AWS Lambda and Step Functions end up with code full of API G
|
|
|
76
76
|
| IBM Code Engine | beta | ✅ | – | – | – | – | embedded |
|
|
77
77
|
| Oracle Cloud Functions | experimental | ✅ | – | – | ✅ | – | embedded |
|
|
78
78
|
| Cloudflare Workers (Python) | experimental | ✅ | ✅ | – | – | – | embedded |
|
|
79
|
-
| On-premises | experimental | ✅ | ✅ | ✅ files | ✅ directory | ✅ files | embedded (
|
|
79
|
+
| On-premises | experimental | ✅ | ✅ | ✅ files | ✅ directory | ✅ files | embedded (local, SSH, or Docker) |
|
|
80
80
|
|
|
81
81
|
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.**
|
|
82
82
|
|
|
@@ -45,10 +45,12 @@ artifact.zip
|
|
|
45
45
|
├── <shim> pskit_entry.py (aws) · main.py (gcp) · function_app.py + host.json (azure)
|
|
46
46
|
│ index.py (alibaba/tencent/huawei) · __main__.py (ibm/do)
|
|
47
47
|
│ func.py + func.yaml + Dockerfile (oracle) · generated worker module (cloudflare)
|
|
48
|
-
│ onprem_handler.py (onprem; the host
|
|
48
|
+
│ onprem_handler.py (onprem; the host is started beside the zip)
|
|
49
49
|
└── dependencies or requirements.txt
|
|
50
50
|
```
|
|
51
51
|
|
|
52
|
+
On-premises also writes `.pskit/onprem-<stage>/onprem_app/` (`pskit_host.json`, `onprem_ctl.py`, `onprem_deploy.py`, the staged bundle, and a Dockerfile or systemd unit when those methods are selected). Terraform `local-exec` runs `onprem_deploy.py apply`, which starts the host on this machine, copies it over SSH (detached process or systemd, optional portable CPython), or builds a Docker image.
|
|
53
|
+
|
|
52
54
|
## Runtime flow
|
|
53
55
|
|
|
54
56
|
```
|
|
@@ -45,7 +45,7 @@ extends: base.yml # inherit another file (see below)
|
|
|
45
45
|
| `iam.statements` | list of `{effect, actions, resources}` | `[]` | AWS-style; `effect` defaults to `Allow`, `resources` to `["*"]`. Ignored (with a warning) on clouds that don't map it |
|
|
46
46
|
| `iam.role` | string | — | use an existing role / agency instead of creating one |
|
|
47
47
|
| `log_retention_days` | int or null | `14` | AWS CloudWatch log group retention |
|
|
48
|
-
| `options` | mapping | `{}` | provider-specific settings, see [providers.md](providers.md) |
|
|
48
|
+
| `options` | mapping | `{}` | provider-specific settings, see [providers.md](providers.md). On-premises: `deploy.method` is `local`, `ssh`, or `docker`; `python: bundle` ships an interpreter when the server has none |
|
|
49
49
|
| `state` | mapping | local state | see [state](#state-remote-terraform-backend) |
|
|
50
50
|
| `terraform` | mapping | | see [terraform](#terraform) |
|
|
51
51
|
|
|
@@ -109,7 +109,7 @@ pskit runs Terraform, so credentials come from each Terraform provider's standar
|
|
|
109
109
|
| `tencent` | `TENCENTCLOUD_SECRET_ID` / `TENCENTCLOUD_SECRET_KEY`, or `options.profile` |
|
|
110
110
|
| `huawei` | `HW_ACCESS_KEY` / `HW_SECRET_KEY` (+ `HW_REGION_NAME`), or `options.profile` |
|
|
111
111
|
| `cloudflare` | `CLOUDFLARE_API_TOKEN`. `options.account_id` is required |
|
|
112
|
-
| `onprem` | nothing to configure
|
|
112
|
+
| `onprem` | local: nothing to configure (the Python that runs `pskit` starts the host). Remote: OpenSSH and `options.deploy.method: ssh`, or Docker and `method: docker`. Servers without Python: `python: bundle` or Docker |
|
|
113
113
|
|
|
114
114
|
Provider-specific required options are listed in [providers.md](providers.md).
|
|
115
115
|
|
|
@@ -95,7 +95,7 @@ def test_workflow():
|
|
|
95
95
|
|
|
96
96
|
## On-premises is a deploy, not `pskit dev`
|
|
97
97
|
|
|
98
|
-
`pskit dev` reloads HTTP handlers and drops the process when you stop it. `provider.name: onprem` is the durable run: `pskit deploy` starts a process that keeps schedules, file queues, directory storage, topics and embedded workflows after the command returns. See [providers.md](providers.md#onprem-on-premises)
|
|
98
|
+
`pskit dev` reloads HTTP handlers and drops the process when you stop it. `provider.name: onprem` is the durable run: `pskit deploy` starts a process that keeps schedules, file queues, directory storage, topics and embedded workflows after the command returns. `options.deploy.method` is `local` (this machine), `ssh`, or `docker`. See [providers.md](providers.md#onprem-on-premises), [`examples/16-on-premises`](../examples/16-on-premises) and [`examples/17-on-premises-remote`](../examples/17-on-premises-remote).
|
|
99
99
|
| `http_event(method, path, body=None, headers=None, query=None)` | dict/list bodies are JSON-encoded; `?query` in `path` is parsed |
|
|
100
100
|
| `build_event(type, data, **http)` | `queue`/`topic` (list → records), `storage` (`{"bucket", "key", "size", "action"}`), `schedule`, `invoke`, `workflow`, `http` |
|
|
101
101
|
|
|
@@ -356,19 +356,19 @@ One Worker script per function. pskit generates a single Python module per Worke
|
|
|
356
356
|
|
|
357
357
|
## onprem (On-premises)
|
|
358
358
|
|
|
359
|
-
- **Terraform:** built-in `terraform_data` (no plugin download)
|
|
360
|
-
- **Credentials:** none
|
|
361
|
-
- **Dependencies:** pip wheels for
|
|
359
|
+
- **Terraform:** built-in `terraform_data` (no plugin download). Create/destroy run `onprem_deploy.py` via `local-exec`
|
|
360
|
+
- **Credentials:** none for `method: local`. SSH keys / an SSH agent for `method: ssh`. Docker CLI (and optional `DOCKER_HOST`) for `method: docker`
|
|
361
|
+
- **Dependencies:** native pip wheels for a local host; manylinux / Windows / macOS wheels matching `deploy.target_os` and `architecture` for a remote host. `tzdata` is vendored so cron timezones work on Windows
|
|
362
362
|
|
|
363
363
|
```yaml
|
|
364
364
|
provider:
|
|
365
365
|
name: onprem
|
|
366
366
|
region: local
|
|
367
367
|
options:
|
|
368
|
-
host: 127.0.0.1 # bind address
|
|
368
|
+
host: 127.0.0.1 # bind address on the *target*. 0.0.0.0 is advertised as 127.0.0.1 unless advertise is set
|
|
369
369
|
port: 8080 # 1-65535. Give each service its own port
|
|
370
370
|
advertise: https://fn.internal.example # optional URL written into outputs
|
|
371
|
-
data_dir: .pskit/onprem-data # default .pskit/onprem-data/<service>-<stage>
|
|
371
|
+
data_dir: .pskit/onprem-data # default .pskit/onprem-data/<service>-<stage> (local); <path>/data on SSH
|
|
372
372
|
poll_seconds: 0.5
|
|
373
373
|
admin_token: "${env:PSKIT_ADMIN_TOKEN, }" # header x-pskit-token on /__pskit/* except health
|
|
374
374
|
services:
|
|
@@ -377,9 +377,11 @@ provider:
|
|
|
377
377
|
storage: {use: directory, path: .onprem/buckets}
|
|
378
378
|
topic: builtin
|
|
379
379
|
workflow: embedded # builtin is an alias of embedded
|
|
380
|
+
deploy:
|
|
381
|
+
method: local # local | ssh | docker (default local)
|
|
380
382
|
```
|
|
381
383
|
|
|
382
|
-
`pskit deploy` writes the bundle under `.pskit/onprem-<stage>/onprem_app/` and
|
|
384
|
+
`pskit deploy` writes the bundle under `.pskit/onprem-<stage>/onprem_app/` and runs `onprem_deploy.py apply`. `pskit remove` stops the process (or container / systemd unit) and does not delete `data_dir`.
|
|
383
385
|
|
|
384
386
|
Omitted services default to `builtin` and are created at start. `existing: true` on one queue, bucket or topic skips that create and waits until the directory appears. Names are a single path segment (`..`, slashes and NUL are rejected).
|
|
385
387
|
|
|
@@ -406,11 +408,47 @@ Publish from outside the process:
|
|
|
406
408
|
|
|
407
409
|
From a handler in that process (`PSKIT_ONPREM_ROOT` is set), call `submit_queue`, `submit_topic`, `put_object` or `delete_object` in `py_serverless_kit.runtime.onprem_host`.
|
|
408
410
|
|
|
409
|
-
**
|
|
411
|
+
**Deploy targets** (`options.deploy`)
|
|
410
412
|
|
|
411
|
-
|
|
413
|
+
| `method` | What runs | Target needs | Laptop needs |
|
|
414
|
+
|---|---|---|---|
|
|
415
|
+
| `local` (default) | detached process on this machine | Python (the interpreter that runs `pskit`) | — |
|
|
416
|
+
| `ssh` | process or systemd unit on a remote host | SSH. Python only if `python: system` | OpenSSH (`ssh`, `scp`) |
|
|
417
|
+
| `docker` | `docker build` + `docker run` | Docker engine, not Python | Docker CLI; set `docker_host: ssh://user@host` to use a remote daemon |
|
|
412
418
|
|
|
413
|
-
|
|
419
|
+
When the server has **no Python**, use `python: bundle` (a portable CPython from [python-build-standalone](https://github.com/astral-sh/python-build-standalone) is fetched at apply and copied with the app) or `method: docker` (the image is `FROM python:<minor>-slim`). Air-gapped: `python_home` (copy a tree you already have) or `python_url` + `python_sha256` (internal mirror of an `install_only` tarball).
|
|
420
|
+
|
|
421
|
+
```yaml
|
|
422
|
+
# SSH + portable CPython + systemd (server does not need Python)
|
|
423
|
+
deploy:
|
|
424
|
+
method: ssh
|
|
425
|
+
host: 10.0.1.12 # or deploy: ssh://pskit@10.0.1.12/opt/pskit/orders
|
|
426
|
+
user: pskit
|
|
427
|
+
port: 22
|
|
428
|
+
identity_file: ${env:PSKIT_SSH_KEY} # optional; otherwise the SSH agent
|
|
429
|
+
known_hosts: accept-new # accept-new | ignore | path to a known_hosts file
|
|
430
|
+
path: /opt/pskit/orders
|
|
431
|
+
python: bundle # auto | system | bundle
|
|
432
|
+
target_os: linux # auto | linux | windows | darwin
|
|
433
|
+
target_arch: x86_64 # auto | x86_64 | arm64 (drives pip wheels)
|
|
434
|
+
install: systemd # process | systemd (linux only)
|
|
435
|
+
sudo: true # needed to write /etc/systemd/system
|
|
436
|
+
|
|
437
|
+
# Docker (server needs Docker, not Python)
|
|
438
|
+
deploy:
|
|
439
|
+
method: docker
|
|
440
|
+
image: pskit/orders:dev
|
|
441
|
+
docker_host: ssh://pskit@10.0.1.12 # empty = Docker on this laptop
|
|
442
|
+
restart: unless-stopped
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
`options.host` is the bind address **on the target**. Use `0.0.0.0` so other machines can call a remote host. `advertise` is the URL stored in `pskit info`. SSH deploy defaults `advertise` to `http://<ssh host>:<port>` when it is unset.
|
|
446
|
+
|
|
447
|
+
**Resources:** `terraform_data.host` with create (`onprem_deploy.py apply`) and destroy (`onprem_deploy.py destroy`) `local-exec` provisioners.
|
|
448
|
+
|
|
449
|
+
**Limits:** no cloud authorizer and no IAM mapping. A `terraform.extra` resource from another cloud (`aws_*`, `google_*`, `azurerm_*`, and the other cloud prefixes) is omitted with a warning. A state backend of `s3`, `gcs` or `azurerm` warns; set `provider.state.backend` empty (see `providers.onprem` in examples 11 and 15) to keep state on this machine. Delivery is at-least-once. A missed schedule fires once on the next poll, not as a burst. The host does not kill a handler at `timeout`; `ctx.remaining_time_ms()` still counts down. If `method` is `local` and `provider.runtime` is not the interpreter running `pskit`, validation warns and the host still uses that interpreter. `python: bundle` needs network on first apply unless `python_home` or a cached archive under `~/.cache/pskit/python-standalone` is present. systemd units are written to `/etc/systemd/system` (set `sudo: true` unless the SSH user is root).
|
|
450
|
+
|
|
451
|
+
Examples: [`examples/16-on-premises`](../examples/16-on-premises) (local process), [`examples/17-on-premises-remote`](../examples/17-on-premises-remote) (SSH / Docker / bundled Python).
|
|
414
452
|
|
|
415
453
|
---
|
|
416
454
|
|
|
@@ -82,7 +82,7 @@ Add `-v` to any command to see the full traceback. Start with `pskit validate`,
|
|
|
82
82
|
| digitalocean | `doctl` must be installed and authenticated (`doctl auth init`); `options.namespace` required; set `options.api_host` to get URLs |
|
|
83
83
|
| ibm | HTTP only, python3.11 only, 120 s / 4 GB max; large bundles → `options.code_reference` |
|
|
84
84
|
| cloudflare | Pyodide: only stdlib and Pyodide packages; `options.account_id` and `CLOUDFLARE_API_TOKEN` required; non-`.py` files aren't uploaded |
|
|
85
|
-
| onprem | one process per service, so give each service its own `options.port`. `pskit remove` stops it and leaves `data_dir`. `auth` must be `none`. A cloud `terraform.extra` resource is omitted. Set `state.backend` empty when the file points at S3, GCS or Azure Storage |
|
|
85
|
+
| onprem | one process per service, so give each service its own `options.port`. `pskit remove` stops it and leaves `data_dir`. `auth` must be `none`. A cloud `terraform.extra` resource is omitted. Set `state.backend` empty when the file points at S3, GCS or Azure Storage. Remote SSH needs `ssh`/`scp` on the laptop; a server without Python needs `deploy.python: bundle` or `method: docker`. systemd writes `/etc/systemd/system` (`sudo: true`). Bind `options.host: 0.0.0.0` on a remote host so other machines can call it |
|
|
86
86
|
| alibaba / tencent / huawei | `iam.statements` aren't translated; set `iam.role` |
|
|
87
87
|
|
|
88
88
|
## FAQ
|
|
@@ -58,3 +58,6 @@ Set `options.admin_token` and send `x-pskit-token` on `/__pskit/*` except
|
|
|
58
58
|
|
|
59
59
|
`pskit dev` is still the hot-reloading HTTP server. This example is the durable
|
|
60
60
|
deploy: it keeps running after `pskit deploy` returns.
|
|
61
|
+
|
|
62
|
+
To copy the same host onto another machine (SSH, Docker, or a bundled CPython
|
|
63
|
+
when that machine has no Python), see [17-on-premises-remote](../17-on-premises-remote).
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# 17 · On-premises, remote server
|
|
2
|
+
|
|
3
|
+
Example 16 runs the host on the laptop that runs `pskit deploy`. This example
|
|
4
|
+
copies the same kind of host onto a machine you SSH into — a factory box, a
|
|
5
|
+
VM, or a rack server. The handler code does not change.
|
|
6
|
+
|
|
7
|
+
Three ways to get code from this laptop onto that server:
|
|
8
|
+
|
|
9
|
+
| `options.deploy.method` | What the server needs | What the laptop needs | When to use it |
|
|
10
|
+
| --- | --- | --- | --- |
|
|
11
|
+
| `local` | this machine (example 16) | Python + pskit | laptop / the server *is* the deploy machine |
|
|
12
|
+
| `ssh` | SSH. Python only if `python: system` | OpenSSH (`ssh`, `scp`) | most on-prem Linux boxes |
|
|
13
|
+
| `docker` | Docker engine | Docker CLI (and SSH if `docker_host` is `ssh://…`) | the server has Docker and you do not want to manage Python |
|
|
14
|
+
|
|
15
|
+
When the server has **no Python**, pick one of:
|
|
16
|
+
|
|
17
|
+
- `method: ssh` and `python: bundle` — pskit downloads a portable CPython
|
|
18
|
+
([python-build-standalone](https://github.com/astral-sh/python-build-standalone))
|
|
19
|
+
at apply time, copies it with the app, and starts systemd (this file)
|
|
20
|
+
- `method: docker` — the image is `FROM python:3.12-slim`; the server never
|
|
21
|
+
installs Python
|
|
22
|
+
- `python_home: /path/to/portable-python` — air-gapped: you already have a
|
|
23
|
+
CPython tree, pskit copies it instead of downloading
|
|
24
|
+
|
|
25
|
+
## This file (SSH + bundled Python + systemd)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
export PSKIT_ONPREM_HOST=10.0.1.12 # SSH target
|
|
29
|
+
export PSKIT_ONPREM_USER=pskit
|
|
30
|
+
export PSKIT_SSH_KEY=$HOME/.ssh/id_ed25519 # optional
|
|
31
|
+
export PSKIT_ONPREM_URL=http://10.0.1.12:8090
|
|
32
|
+
pskit deploy
|
|
33
|
+
curl http://10.0.1.12:8090/hello?name=Ada
|
|
34
|
+
pskit remove # systemctl stop; data dir stays
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The SSH user needs `sudo` to write `/etc/systemd/system` (`deploy.sudo: true`).
|
|
38
|
+
Wheels are vendored as manylinux x86_64 because `target_os: linux`.
|
|
39
|
+
|
|
40
|
+
Shorthand for the same method:
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
deploy: ssh://pskit@10.0.1.12/opt/pskit/factory-api
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Docker instead
|
|
47
|
+
|
|
48
|
+
The server needs a Docker engine. It does not need Python.
|
|
49
|
+
|
|
50
|
+
```yaml
|
|
51
|
+
provider:
|
|
52
|
+
options:
|
|
53
|
+
host: 0.0.0.0
|
|
54
|
+
port: 8090
|
|
55
|
+
deploy:
|
|
56
|
+
method: docker
|
|
57
|
+
image: pskit/factory-api:dev
|
|
58
|
+
docker_host: ssh://pskit@10.0.1.12 # empty = Docker on this laptop
|
|
59
|
+
restart: unless-stopped
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`pskit deploy` runs `docker build` and `docker run` (with `DOCKER_HOST` when
|
|
63
|
+
`docker_host` is set). Data lives in a volume named after the container.
|
|
64
|
+
|
|
65
|
+
## Server already has Python
|
|
66
|
+
|
|
67
|
+
```yaml
|
|
68
|
+
deploy:
|
|
69
|
+
method: ssh
|
|
70
|
+
host: 10.0.1.12
|
|
71
|
+
user: pskit
|
|
72
|
+
path: /opt/pskit/factory-api
|
|
73
|
+
python: system # uses python3.12 on the server
|
|
74
|
+
install: process # start a detached process instead of systemd
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Air-gapped bundle
|
|
78
|
+
|
|
79
|
+
Download the install_only archive once on a machine with network, copy it in,
|
|
80
|
+
and point at the unpacked tree:
|
|
81
|
+
|
|
82
|
+
```yaml
|
|
83
|
+
deploy:
|
|
84
|
+
method: ssh
|
|
85
|
+
host: 10.0.1.12
|
|
86
|
+
python: bundle
|
|
87
|
+
python_home: ./vendor/python # portable CPython directory, copied as-is
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Or set `python_url` + `python_sha256` to an internal mirror of the
|
|
91
|
+
python-build-standalone `install_only` tarball.
|
|
92
|
+
|
|
93
|
+
## Bind address
|
|
94
|
+
|
|
95
|
+
`options.host` is the address the process binds on the **target**. Use
|
|
96
|
+
`0.0.0.0` so other machines can call it. `advertise` is the URL written into
|
|
97
|
+
`pskit info` and the dashboard.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Package marker.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"""Handlers for a remote on-premises deploy. Identical to a cloud function."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from py_serverless_kit import Context, Event
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def hello(event: Event, ctx: Context):
|
|
9
|
+
name = event.http.query.get("name", "world")
|
|
10
|
+
ctx.logger.info("greeting", extra={"name": name})
|
|
11
|
+
return {"message": f"Hello, {name}!", "provider": event.provider, "stage": ctx.stage, "host": "remote"}
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def tick(event: Event, ctx: Context):
|
|
15
|
+
ctx.logger.info("tick", extra={"data": event.data})
|
|
16
|
+
return {"ok": True, "data": event.data}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Remote on-premises deploy.
|
|
2
|
+
#
|
|
3
|
+
# This file ships the function bundle to a Linux server that may not have Python.
|
|
4
|
+
# `python: bundle` downloads a portable CPython at apply time and copies it with
|
|
5
|
+
# the app. `install: systemd` keeps the host up across reboots.
|
|
6
|
+
#
|
|
7
|
+
# Required on the laptop: OpenSSH (`ssh`, `scp`). Required on the server: SSH
|
|
8
|
+
# access. Python on the server is optional.
|
|
9
|
+
#
|
|
10
|
+
# set PSKIT_ONPREM_HOST=10.0.1.12
|
|
11
|
+
# pskit deploy
|
|
12
|
+
#
|
|
13
|
+
# Switch to Docker (server needs Docker, not Python) with the `providers.onprem`
|
|
14
|
+
# block left as-is and:
|
|
15
|
+
# pskit deploy after changing deploy.method to docker (see README).
|
|
16
|
+
service: factory-api
|
|
17
|
+
|
|
18
|
+
provider:
|
|
19
|
+
name: onprem
|
|
20
|
+
region: local
|
|
21
|
+
runtime: python3.12
|
|
22
|
+
architecture: x86_64
|
|
23
|
+
options:
|
|
24
|
+
host: 0.0.0.0
|
|
25
|
+
port: 8090
|
|
26
|
+
advertise: "${env:PSKIT_ONPREM_URL, http://127.0.0.1:8090}"
|
|
27
|
+
data_dir: /opt/pskit/factory-api/data
|
|
28
|
+
deploy:
|
|
29
|
+
method: ssh
|
|
30
|
+
host: "${env:PSKIT_ONPREM_HOST, 127.0.0.1}"
|
|
31
|
+
user: "${env:PSKIT_ONPREM_USER, pskit}"
|
|
32
|
+
port: 22
|
|
33
|
+
identity_file: "${env:PSKIT_SSH_KEY, }"
|
|
34
|
+
known_hosts: accept-new
|
|
35
|
+
path: /opt/pskit/factory-api
|
|
36
|
+
python: bundle
|
|
37
|
+
target_os: linux
|
|
38
|
+
target_arch: x86_64
|
|
39
|
+
install: systemd
|
|
40
|
+
sudo: true
|
|
41
|
+
|
|
42
|
+
functions:
|
|
43
|
+
hello:
|
|
44
|
+
handler: app.handlers.hello
|
|
45
|
+
events:
|
|
46
|
+
- http: GET /hello
|
|
47
|
+
tick:
|
|
48
|
+
handler: app.handlers.tick
|
|
49
|
+
events:
|
|
50
|
+
- schedule: {rate: 1 hour, input: {source: factory}}
|
|
51
|
+
|
|
52
|
+
providers:
|
|
53
|
+
aws:
|
|
54
|
+
region: us-east-1
|
|
55
|
+
gcp:
|
|
56
|
+
region: us-central1
|
|
57
|
+
options: {project: "${env:GOOGLE_CLOUD_PROJECT, my-gcp-project}"}
|
|
58
|
+
azure:
|
|
59
|
+
region: eastus
|
|
60
|
+
options: {subscription_id: "${env:ARM_SUBSCRIPTION_ID, 00000000-0000-0000-0000-000000000000}"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# No third-party dependencies. The pskit runtime is vendored into the bundle automatically.
|
|
@@ -23,6 +23,7 @@ by changing only the provider (`pskit deploy --provider gcp`).
|
|
|
23
23
|
| 14 | [testing](14-testing) | pytest with `LocalRunner`, synthetic events, workflow tests, CI validation | AWS, GCP, Azure |
|
|
24
24
|
| 15 | [ci-cd-deploy](15-ci-cd-deploy) | GitHub Actions per-stage deploys with OIDC, remote state, dashboard artifact | AWS, GCP, Azure |
|
|
25
25
|
| 16 | [on-premises](16-on-premises) | one process on this machine: HTTP, schedule, queue, directory storage, topic, embedded workflow | on-premises |
|
|
26
|
+
| 17 | [on-premises-remote](17-on-premises-remote) | SSH / Docker / bundled CPython onto a server that may not have Python | on-premises |
|
|
26
27
|
|
|
27
28
|
\* Azure blob triggers can't fire on deletions; the example's `providers.azure` block
|
|
28
29
|
handles that explicitly.
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.3.0"
|
|
2
2
|
__author__ = "Asif Khan @ Kavion.ai"
|
|
@@ -31,6 +31,9 @@ PROVIDER_OPTIONS = {
|
|
|
31
31
|
" options:\n"
|
|
32
32
|
" host: 127.0.0.1\n"
|
|
33
33
|
" port: 8080\n"
|
|
34
|
+
" # deploy.method: local (this machine) | ssh | docker\n"
|
|
35
|
+
" # ssh: {host: 10.0.1.12, user: pskit, python: bundle, install: systemd}\n"
|
|
36
|
+
" # python: bundle ships a portable CPython when the server has none\n"
|
|
34
37
|
" # builtin services are created on deploy. To use a directory you already\n"
|
|
35
38
|
" # have: storage: {use: directory, path: /var/pskit/buckets}\n"
|
|
36
39
|
),
|
{py_serverless_kit-0.2.0 → py_serverless_kit-0.3.0}/src/py_serverless_kit/packaging/builder.py
RENAMED
|
@@ -238,7 +238,7 @@ def build_artifact(project: Project, *, skip_deps: bool = False, log=print) -> A
|
|
|
238
238
|
if final_reqs and not skip_deps:
|
|
239
239
|
req_file = work / "requirements.vendor.txt"
|
|
240
240
|
req_file.write_text("\n".join(final_reqs) + "\n", "utf-8")
|
|
241
|
-
flags = provider.
|
|
241
|
+
flags = provider.pip_platform_for(cfg)
|
|
242
242
|
log(f" vendoring {len(final_reqs)} requirement(s) for {cfg.provider.runtime}/{cfg.provider.architecture}")
|
|
243
243
|
_pip_install(req_file, build_dir, flags, cfg.package.pip_args)
|
|
244
244
|
else:
|
|
@@ -191,6 +191,9 @@ class Provider(ABC):
|
|
|
191
191
|
"--only-binary=:all:",
|
|
192
192
|
]
|
|
193
193
|
|
|
194
|
+
def pip_platform_for(self, config: ServiceConfig) -> List[str]:
|
|
195
|
+
return self.pip_platform(config.provider.runtime, config.provider.architecture)
|
|
196
|
+
|
|
194
197
|
# ------------------------------------------------------------ validation
|
|
195
198
|
def workflow_engine(self, wf: WorkflowConfig) -> str:
|
|
196
199
|
if wf.engine == "native":
|