diff --git a/cloud/alibaba-fc-scheduled/README.md b/cloud/alibaba-fc-scheduled/README.md index f0f6a04..5bb0a44 100644 --- a/cloud/alibaba-fc-scheduled/README.md +++ b/cloud/alibaba-fc-scheduled/README.md @@ -56,7 +56,7 @@ The timer trigger uses **cron expressions** (China Standard Time — UTC+8): ## Important - Do not rename `handler.py` or the `handler()` function — `s.yaml` references `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The `s.yaml` has the function name, region, container image, and schedule pre-configured from cookiecutter - Timer triggers use China Standard Time (CST/UTC+8) by default - To change the schedule after deploy, edit `cronExpression` in `s.yaml` and run `s deploy` again diff --git a/cloud/alibaba-fc-scheduled/handler.py b/cloud/alibaba-fc-scheduled/handler.py index 40245d9..304da01 100644 --- a/cloud/alibaba-fc-scheduled/handler.py +++ b/cloud/alibaba-fc-scheduled/handler.py @@ -7,5 +7,5 @@ def handler(event, context): """Invoked by Timer Trigger on a schedule.""" - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} diff --git a/cloud/alibaba-fc/README.md b/cloud/alibaba-fc/README.md index 7f7ad12..21baf61 100644 --- a/cloud/alibaba-fc/README.md +++ b/cloud/alibaba-fc/README.md @@ -45,6 +45,6 @@ s logs --tail ## Important - Do not rename `handler.py` or the `handler()` function — `s.yaml` references `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The `s.yaml` has the function name, region, and container image pre-configured from cookiecutter - To add triggers (HTTP, timer, OSS, etc.), edit the `triggers` section in `s.yaml` diff --git a/cloud/alibaba-fc/handler.py b/cloud/alibaba-fc/handler.py index ddf4394..2b0d768 100644 --- a/cloud/alibaba-fc/handler.py +++ b/cloud/alibaba-fc/handler.py @@ -6,5 +6,5 @@ def handler(event, context): - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} diff --git a/cloud/azure-container/Dockerfile b/cloud/azure-container/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/azure-container/Dockerfile +++ b/cloud/azure-container/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/cloud-run-scheduled/Dockerfile b/cloud/cloud-run-scheduled/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/cloud-run-scheduled/Dockerfile +++ b/cloud/cloud-run-scheduled/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/cloud-run-scheduled/README.md b/cloud/cloud-run-scheduled/README.md index 828c1ac..0621747 100644 --- a/cloud/cloud-run-scheduled/README.md +++ b/cloud/cloud-run-scheduled/README.md @@ -35,7 +35,7 @@ gcloud logging read "resource.type=cloud_run_revision AND resource.labels.servic ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `cloudbuild.yaml` references `gcp_project_id` and `gcp_region` — these must match your GCP project - Replace `` with the actual URL from the `gcloud run deploy` output - The scheduler uses OIDC authentication to invoke the Cloud Run service diff --git a/cloud/cloud-run/Dockerfile b/cloud/cloud-run/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/cloud-run/Dockerfile +++ b/cloud/cloud-run/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/cloud-run/README.md b/cloud/cloud-run/README.md index d068b3e..296c73a 100644 --- a/cloud/cloud-run/README.md +++ b/cloud/cloud-run/README.md @@ -27,6 +27,6 @@ gcloud logging read "resource.type=cloud_run_revision AND resource.labels.servic ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `cloudbuild.yaml` references `gcp_project_id` and `gcp_region` — these must match your GCP project - Enable all required APIs before deploying diff --git a/cloud/digital-ocean/Dockerfile b/cloud/digital-ocean/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/digital-ocean/Dockerfile +++ b/cloud/digital-ocean/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/docker/Dockerfile b/cloud/docker/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/docker/Dockerfile +++ b/cloud/docker/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/docker/README.md b/cloud/docker/README.md index 0de5d98..6ad61ff 100644 --- a/cloud/docker/README.md +++ b/cloud/docker/README.md @@ -15,5 +15,5 @@ docker compose up ## Important -- Do not rename the `workflow.py` module or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `docker-compose.yml` uses the `project_name` as container name diff --git a/cloud/dotflow-cloud/README.md b/cloud/dotflow-cloud/README.md new file mode 100644 index 0000000..f96b19b --- /dev/null +++ b/cloud/dotflow-cloud/README.md @@ -0,0 +1,28 @@ +# Dotflow Cloud + +Managed execution runtime for dotflow pipelines. Run your workflow on Dotflow Cloud without managing infrastructure. + +## Workflow entrypoint + +Your `workflow.py` must expose a `main()` factory that returns a `DotFlow` instance: + +```python +from dotflow import DotFlow + +def main() -> DotFlow: + workflow = DotFlow() + workflow.task.add(step=[...], initial_context=...) + return workflow +``` + +Dotflow Cloud runs it with the same contract used by: + +```bash +dotflow start --workflow .workflow:main +``` + +## Deploy + +```bash +dotflow deploy --platform dotflow-cloud --project +``` diff --git a/cloud/ecs-scheduled/Dockerfile b/cloud/ecs-scheduled/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/ecs-scheduled/Dockerfile +++ b/cloud/ecs-scheduled/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/ecs-scheduled/README.md b/cloud/ecs-scheduled/README.md index 078d65c..7ba19ae 100644 --- a/cloud/ecs-scheduled/README.md +++ b/cloud/ecs-scheduled/README.md @@ -40,7 +40,7 @@ aws logs get-log-events --log-group-name /ecs/ \ ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The schedule expression in `template.yaml` uses AWS EventBridge syntax - Edit `aws_account_id` and `aws_region` in `template.yaml` before deploying - The ECS task runs on Fargate and stops after the workflow completes diff --git a/cloud/ecs/Dockerfile b/cloud/ecs/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/ecs/Dockerfile +++ b/cloud/ecs/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/ecs/README.md b/cloud/ecs/README.md index e7f98d9..0d692c3 100644 --- a/cloud/ecs/README.md +++ b/cloud/ecs/README.md @@ -53,7 +53,7 @@ aws logs get-log-events --log-group-name /ecs/ \ ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `task-definition.json` references the ECR image URI, `executionRoleArn`, and CloudWatch log group — do not change these unless you also update the corresponding AWS resources - The `aws_account_id` and `aws_region` must match your actual AWS account and region - Create the CloudWatch log group before running the task, otherwise the container will fail to start diff --git a/cloud/fly-io/Dockerfile b/cloud/fly-io/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/fly-io/Dockerfile +++ b/cloud/fly-io/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/fly-io/fly.toml b/cloud/fly-io/fly.toml index 4f5d984..bac2764 100644 --- a/cloud/fly-io/fly.toml +++ b/cloud/fly-io/fly.toml @@ -5,7 +5,7 @@ primary_region = "iad" dockerfile = "Dockerfile" [processes] - worker = "python -m {{MODULE_NAME}}.workflow" + worker = "dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}}" [[vm]] cpu_kind = "shared" diff --git a/cloud/github-actions/.github/workflows/dotflow.yml b/cloud/github-actions/.github/workflows/dotflow.yml index ce081f4..4efe244 100644 --- a/cloud/github-actions/.github/workflows/dotflow.yml +++ b/cloud/github-actions/.github/workflows/dotflow.yml @@ -17,4 +17,4 @@ jobs: - run: pip install -e . - - run: python -m {{MODULE_NAME}}.workflow + - run: dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}} diff --git a/cloud/heroku/Dockerfile b/cloud/heroku/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/heroku/Dockerfile +++ b/cloud/heroku/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/heroku/Procfile b/cloud/heroku/Procfile index 788b261..ec120a4 100644 --- a/cloud/heroku/Procfile +++ b/cloud/heroku/Procfile @@ -1 +1 @@ -worker: python -m {{MODULE_NAME}}.workflow +worker: dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}} diff --git a/cloud/heroku/heroku.yml b/cloud/heroku/heroku.yml index 9276305..1b34ba6 100644 --- a/cloud/heroku/heroku.yml +++ b/cloud/heroku/heroku.yml @@ -5,6 +5,9 @@ build: run: worker: command: - - python - - -m - - {{MODULE_NAME}}.workflow + - dotflow + - start + - --workflow + - {{MODULE_NAME}}.workflow:main + - --mode + - {{EXECUTION_MODE}} diff --git a/cloud/kubernetes/Dockerfile b/cloud/kubernetes/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/kubernetes/Dockerfile +++ b/cloud/kubernetes/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/kubernetes/README.md b/cloud/kubernetes/README.md index 4262de6..a442fee 100644 --- a/cloud/kubernetes/README.md +++ b/cloud/kubernetes/README.md @@ -43,6 +43,6 @@ kubectl apply -f service.yaml ## Important -- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` CMD depends on it +- Do not rename `workflow.py` or the `main()` function — the `Dockerfile` runs `dotflow start --workflow .workflow:main` - The `deployment.yaml` uses `imagePullPolicy: Never` by default — this only works with locally built images (minikube). For production, change to `Always` and use a container registry - Project names with `_` are automatically converted to `-` in Kubernetes resource names (RFC 1123 compliance) diff --git a/cloud/lambda-api-trigger/README.md b/cloud/lambda-api-trigger/README.md index 26cf7ce..9c15e00 100644 --- a/cloud/lambda-api-trigger/README.md +++ b/cloud/lambda-api-trigger/README.md @@ -45,6 +45,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The API Gateway URL is shown in the CloudFormation outputs after deploy - The `samconfig.toml` has stack name, region, and ECR repository pre-configured diff --git a/cloud/lambda-api-trigger/handler.py b/cloud/lambda-api-trigger/handler.py index e0db4a9..6e02fb4 100644 --- a/cloud/lambda-api-trigger/handler.py +++ b/cloud/lambda-api-trigger/handler.py @@ -11,5 +11,5 @@ def handler(event, context): body = json.loads(event.get("body") or "{}") print(f"Received payload: {body}") - result = main() + main() return {"statusCode": 200, "body": json.dumps({"status": "workflow executed"})} diff --git a/cloud/lambda-s3-trigger/README.md b/cloud/lambda-s3-trigger/README.md index 391259c..2a5d196 100644 --- a/cloud/lambda-s3-trigger/README.md +++ b/cloud/lambda-s3-trigger/README.md @@ -41,6 +41,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - Edit the S3 bucket name and prefix in `template.yaml` before deploying - The `samconfig.toml` has stack name, region, and ECR repository pre-configured diff --git a/cloud/lambda-s3-trigger/handler.py b/cloud/lambda-s3-trigger/handler.py index 7d09af8..8f22161 100644 --- a/cloud/lambda-s3-trigger/handler.py +++ b/cloud/lambda-s3-trigger/handler.py @@ -7,5 +7,5 @@ def handler(event, context): """Invoked by S3 file upload.""" - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} diff --git a/cloud/lambda-scheduled/README.md b/cloud/lambda-scheduled/README.md index c1f908b..8d43ade 100644 --- a/cloud/lambda-scheduled/README.md +++ b/cloud/lambda-scheduled/README.md @@ -35,6 +35,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The schedule expression in `template.yaml` uses AWS EventBridge syntax (e.g. `rate(6 hours)`, `cron(0 12 * * ? *)`) - The `samconfig.toml` has stack name, region, and ECR repository pre-configured diff --git a/cloud/lambda-scheduled/handler.py b/cloud/lambda-scheduled/handler.py index 1234085..408f94a 100644 --- a/cloud/lambda-scheduled/handler.py +++ b/cloud/lambda-scheduled/handler.py @@ -7,5 +7,5 @@ def handler(event, context): """Invoked by EventBridge on a schedule.""" - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} diff --git a/cloud/lambda-sqs-trigger/README.md b/cloud/lambda-sqs-trigger/README.md index 1306e70..e2fcf5f 100644 --- a/cloud/lambda-sqs-trigger/README.md +++ b/cloud/lambda-sqs-trigger/README.md @@ -41,6 +41,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The SQS queue is created by the SAM template — check `template.yaml` for queue configuration - The `samconfig.toml` has stack name, region, and ECR repository pre-configured diff --git a/cloud/lambda-sqs-trigger/handler.py b/cloud/lambda-sqs-trigger/handler.py index 1c9f850..e41fd8b 100644 --- a/cloud/lambda-sqs-trigger/handler.py +++ b/cloud/lambda-sqs-trigger/handler.py @@ -12,5 +12,5 @@ def handler(event, context): body = json.loads(record.get("body", "{}")) print(f"Received message: {body}") - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} diff --git a/cloud/lambda/README.md b/cloud/lambda/README.md index 6b9b211..e69dc76 100644 --- a/cloud/lambda/README.md +++ b/cloud/lambda/README.md @@ -35,6 +35,6 @@ sam logs --stack-name --tail ## Important - Do not rename `handler.py` or the `handler()` function — the `Dockerfile` CMD is `handler.handler` -- Do not rename `workflow.py` or the `main()` function — `handler.py` imports it +- Do not rename `workflow.py` or the `main()` function — `handler.py` calls `main()` which starts the workflow internally - The `samconfig.toml` has the stack name, region, and ECR repository pre-configured from cookiecutter - To change the schedule or add triggers, edit `template.yaml` (see `lambda-scheduled` template) diff --git a/cloud/lambda/handler.py b/cloud/lambda/handler.py index ddf4394..2b0d768 100644 --- a/cloud/lambda/handler.py +++ b/cloud/lambda/handler.py @@ -6,5 +6,5 @@ def handler(event, context): - result = main() + main() return {"statusCode": 200, "body": "workflow executed"} diff --git a/cloud/railway/Dockerfile b/cloud/railway/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/railway/Dockerfile +++ b/cloud/railway/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cloud/railway/railway.json b/cloud/railway/railway.json index 8052ce1..c7c5153 100644 --- a/cloud/railway/railway.json +++ b/cloud/railway/railway.json @@ -5,7 +5,7 @@ "dockerfilePath": "Dockerfile" }, "deploy": { - "startCommand": "python -m {{MODULE_NAME}}.workflow", + "startCommand": "dotflow start --workflow {{MODULE_NAME}}.workflow:main --mode {{EXECUTION_MODE}}", "restartPolicyType": "ON_FAILURE", "restartPolicyMaxRetries": 3 } diff --git a/cloud/registry.json b/cloud/registry.json index b9d051f..275150f 100644 --- a/cloud/registry.json +++ b/cloud/registry.json @@ -5,6 +5,11 @@ "description": "Dockerfile and docker-compose for local or any container runtime", "files": ["Dockerfile", "docker-compose.yml", "README.md"] }, + "dotflow-cloud": { + "name": "Dotflow Cloud", + "description": "Managed dotflow runtime with workflow factory entrypoint (dotflow start --workflow)", + "files": ["README.md"] + }, "lambda": { "name": "AWS Lambda", "description": "Dockerfile, handler.py, and SAM template for AWS Lambda", diff --git a/cloud/render/Dockerfile b/cloud/render/Dockerfile index b4c453e..b8549a3 100644 --- a/cloud/render/Dockerfile +++ b/cloud/render/Dockerfile @@ -6,4 +6,4 @@ COPY . . RUN pip install --no-cache-dir -e . -CMD ["python", "-m", "{{MODULE_NAME}}.workflow"] +CMD ["dotflow", "start", "--workflow", "{{MODULE_NAME}}.workflow:main", "--mode", "{{EXECUTION_MODE}}"] diff --git a/cookiecutter.json b/cookiecutter.json index db72c11..dd410d1 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -6,5 +6,5 @@ "execution_mode": ["sequential", "parallel", "background"], "retry": ["no", "yes"], "checkpoint": ["no", "yes"], - "cloud": ["none", "docker", "lambda", "lambda-scheduled", "lambda-s3-trigger", "lambda-sqs-trigger", "lambda-api-trigger", "ecs", "ecs-scheduled", "cloud-run", "cloud-run-scheduled", "kubernetes", "github-actions", "alibaba-fc", "alibaba-fc-scheduled"] + "cloud": ["none", "dotflow-cloud", "docker", "lambda", "lambda-scheduled", "lambda-s3-trigger", "lambda-sqs-trigger", "lambda-api-trigger", "ecs", "ecs-scheduled", "cloud-run", "cloud-run-scheduled", "kubernetes", "github-actions", "alibaba-fc", "alibaba-fc-scheduled"] } diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index 3920358..48dae38 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -11,6 +11,7 @@ CLOUD = "{{ cookiecutter.cloud }}" PROJECT_NAME = "{{ cookiecutter.project_name }}" MODULE_NAME = "{{ cookiecutter.module_name }}" +EXECUTION_MODE = "{{ cookiecutter.execution_mode }}" BOLD = "\033[1m" CYAN = "\033[36m" @@ -33,6 +34,7 @@ def ask_inputs() -> dict: "MODULE_NAME": MODULE_NAME, "STACK_NAME": sanitized_name, "K8S_NAME": sanitized_name, + "EXECUTION_MODE": EXECUTION_MODE, } if CLOUD in { diff --git a/{{cookiecutter.project_name}}/README.md b/{{cookiecutter.project_name}}/README.md index 1dd390e..f806c2a 100644 --- a/{{cookiecutter.project_name}}/README.md +++ b/{{cookiecutter.project_name}}/README.md @@ -16,7 +16,7 @@ A workflow built with [dotflow](https://github.com/dotflow-io/dotflow). ```bash pip install -e ".[dev]" -python -m {{ cookiecutter.module_name }}.workflow +dotflow start --workflow {{ cookiecutter.module_name }}.workflow:main --mode {{ cookiecutter.execution_mode }} ``` ## Running Tests diff --git a/{{cookiecutter.project_name}}/pyproject.toml b/{{cookiecutter.project_name}}/pyproject.toml index 8c61786..a5e3255 100644 --- a/{{cookiecutter.project_name}}/pyproject.toml +++ b/{{cookiecutter.project_name}}/pyproject.toml @@ -1,15 +1,17 @@ +{%- set scheduled_clouds = ["dotflow-cloud", "lambda-scheduled", "ecs-scheduled", "cloud-run-scheduled", "alibaba-fc-scheduled", "github-actions"] -%} +{%- set scheduler = "none" if cookiecutter.cloud in scheduled_clouds else cookiecutter.scheduler -%} [project] name = "{{ cookiecutter.project_name }}" version = "0.1.0" description = "" requires-python = ">=3.9" dependencies = [ -{% if cookiecutter.storage == "s3" and cookiecutter.scheduler == "cron" %} "dotflow==0.15.0.dev7[aws,scheduler]", -{% elif cookiecutter.storage == "gcs" and cookiecutter.scheduler == "cron" %} "dotflow==0.15.0.dev7[gcp,scheduler]", -{% elif cookiecutter.storage == "s3" %} "dotflow==0.15.0.dev7[aws]", -{% elif cookiecutter.storage == "gcs" %} "dotflow==0.15.0.dev7[gcp]", -{% elif cookiecutter.scheduler == "cron" %} "dotflow==0.15.0.dev7[scheduler]", -{% else %} "dotflow==0.15.0.dev7", +{% if cookiecutter.storage == "s3" and scheduler == "cron" %} "dotflow==1.0.0.dev3[aws,scheduler]", +{% elif cookiecutter.storage == "gcs" and scheduler == "cron" %} "dotflow==1.0.0.dev3[gcp,scheduler]", +{% elif cookiecutter.storage == "s3" %} "dotflow==1.0.0.dev3[aws]", +{% elif cookiecutter.storage == "gcs" %} "dotflow==1.0.0.dev3[gcp]", +{% elif scheduler == "cron" %} "dotflow==1.0.0.dev3[scheduler]", +{% else %} "dotflow==1.0.0.dev3", {% endif %}] [project.optional-dependencies] diff --git a/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py b/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py index 85bf1d5..1a0eb26 100644 --- a/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py +++ b/{{cookiecutter.project_name}}/{{cookiecutter.module_name}}/workflow.py @@ -1,3 +1,6 @@ +{%- set scheduled_clouds = ["dotflow-cloud", "lambda-scheduled", "ecs-scheduled", "cloud-run-scheduled", "alibaba-fc-scheduled", "github-actions"] -%} +{%- set scheduler = "none" if cookiecutter.cloud in scheduled_clouds else cookiecutter.scheduler -%} +{%- set needs_internal_start = cookiecutter.cloud in ["lambda", "lambda-scheduled", "lambda-s3-trigger", "lambda-sqs-trigger", "lambda-api-trigger", "alibaba-fc", "alibaba-fc-scheduled"] -%} {% if cookiecutter.checkpoint == "yes" -%} from uuid import uuid4 {% endif -%} @@ -9,25 +12,25 @@ {% elif cookiecutter.storage == "gcs" -%} from dotflow.providers import StorageGCS {% endif -%} -{% if cookiecutter.scheduler == "cron" -%} +{% if scheduler == "cron" -%} from dotflow.providers import SchedulerCron {% endif %} from {{ cookiecutter.module_name }}.actions import step_one, step_two -{% if cookiecutter.storage == "default" and cookiecutter.scheduler == "none" -%} +{% if cookiecutter.storage == "default" and scheduler == "none" -%} config = Config() -{% elif cookiecutter.storage == "default" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "default" and scheduler == "cron" -%} config = Config( scheduler=SchedulerCron(cron="*/5 * * * *"), ) -{% elif cookiecutter.storage == "file" and cookiecutter.scheduler == "none" -%} +{% elif cookiecutter.storage == "file" and scheduler == "none" -%} config = Config(storage=StorageFile()) -{% elif cookiecutter.storage == "file" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "file" and scheduler == "cron" -%} config = Config( storage=StorageFile(), scheduler=SchedulerCron(cron="*/5 * * * *"), ) -{% elif cookiecutter.storage == "s3" and cookiecutter.scheduler == "none" -%} +{% elif cookiecutter.storage == "s3" and scheduler == "none" -%} config = Config( storage=StorageS3( bucket="my-dotflow-bucket", @@ -35,7 +38,7 @@ region="us-east-1", ) ) -{% elif cookiecutter.storage == "s3" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "s3" and scheduler == "cron" -%} config = Config( storage=StorageS3( bucket="my-dotflow-bucket", @@ -44,7 +47,7 @@ ), scheduler=SchedulerCron(cron="*/5 * * * *"), ) -{% elif cookiecutter.storage == "gcs" and cookiecutter.scheduler == "none" -%} +{% elif cookiecutter.storage == "gcs" and scheduler == "none" -%} config = Config( storage=StorageGCS( bucket="my-dotflow-bucket", @@ -52,7 +55,7 @@ project="my-gcp-project", ) ) -{% elif cookiecutter.storage == "gcs" and cookiecutter.scheduler == "cron" -%} +{% elif cookiecutter.storage == "gcs" and scheduler == "cron" -%} config = Config( storage=StorageGCS( bucket="my-dotflow-bucket", @@ -63,7 +66,7 @@ ) {% endif %} -def main(): +def main() -> DotFlow: {%- if cookiecutter.checkpoint == "yes" %} workflow = DotFlow(config=config, workflow_id=uuid4()) {%- else %} @@ -72,22 +75,11 @@ def main(): workflow.task.add(step=step_one) workflow.task.add(step=step_two) - -{%- if cookiecutter.scheduler == "cron" and cookiecutter.checkpoint == "yes" %} - workflow.schedule(mode="{{ cookiecutter.execution_mode }}", resume=True) -{%- elif cookiecutter.scheduler == "cron" %} - workflow.schedule(mode="{{ cookiecutter.execution_mode }}") -{%- elif cookiecutter.checkpoint == "yes" %} +{% if needs_internal_start %} +{%- if cookiecutter.checkpoint == "yes" %} workflow.start(mode="{{ cookiecutter.execution_mode }}", resume=True) {%- else %} workflow.start(mode="{{ cookiecutter.execution_mode }}") {%- endif %} - - for task in workflow.result_task(): - print(f"Task {task.task_id}: {task.status}") - +{% endif %} return workflow - - -if __name__ == "__main__": - main()