{"id":15527279,"url":"https://github.com/mongkok/seda","last_synced_at":"2025-04-23T12:16:35.823Z","repository":{"id":135921839,"uuid":"586937115","full_name":"mongkok/seda","owner":"mongkok","description":"A Python toolkit to schedule periodic and one-time tasks on AWS Lambda","archived":false,"fork":false,"pushed_at":"2023-01-11T03:13:57.000Z","size":37,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-23T12:16:16.612Z","etag":null,"topics":["asgi","async","asynchronous","aws","cloudwatch","cron","django","event-driven","eventbridge","events","falcon","fastapi","lambda","schedule","scheduler","serverless","sns","starlette","tasks"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mongkok.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-09T15:27:33.000Z","updated_at":"2023-08-01T05:32:02.000Z","dependencies_parsed_at":null,"dependency_job_id":"b496be65-50d5-441b-bfd7-60e6d97a31c1","html_url":"https://github.com/mongkok/seda","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongkok%2Fseda","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongkok%2Fseda/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongkok%2Fseda/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mongkok%2Fseda/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mongkok","download_url":"https://codeload.github.com/mongkok/seda/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250430600,"owners_count":21429324,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asgi","async","asynchronous","aws","cloudwatch","cron","django","event-driven","eventbridge","events","falcon","fastapi","lambda","schedule","scheduler","serverless","sns","starlette","tasks"],"created_at":"2024-10-02T11:05:21.915Z","updated_at":"2025-04-23T12:16:35.815Z","avatar_url":"https://github.com/mongkok.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SEDA\n\n\u003cp align=\"center\"\u003e\n    \u003cem\u003eA Python toolkit to build \u003cb\u003eS\u003c/b\u003eerverless \u003cb\u003eE\u003c/b\u003event-\u003cb\u003eD\u003c/b\u003eriven \u003cb\u003eA\u003c/b\u003epplications on AWS.\u003c/em\u003e\n    \u003cbr\u003e\u003cem\u003eDocumentation: \u003ca href=\"https://seda.domake.io\"\u003e\u003cdel\u003ehttps://seda.domake.io\u003c/del\u003e\u003c/a\u003e (pending)\u003c/em\u003e\n    \u003cbr\u003e\u003cem\u003e\u003cb\u003eExamples: \u003ca href=\"https://github.com/mongkok/seda/tree/main/templates\"\u003e/templates\u003c/a\u003e\u003c/b\u003e\u003c/em\u003e\n\u003c/p\u003e\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/mongkok/seda/actions\"\u003e\n        \u003cimg src=\"https://github.com/mongkok/seda/actions/workflows/test-suite.yml/badge.svg\" alt=\"Test\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/mongkok/seda\"\u003e\n        \u003cimg src=\"https://img.shields.io/codecov/c/github/mongkok/seda?color=%2334D058\" alt=\"Coverage\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.codacy.com/gh/mongkok/seda/dashboard\"\u003e\n        \u003cimg src=\"https://app.codacy.com/project/badge/Grade/ee6de85d485d4d9fbb5592ac95cec155\" alt=\"Codacy\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/seda\"\u003e\n        \u003cimg src=\"https://img.shields.io/pypi/v/seda\" alt=\"Package version\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n## What\n\n*   [x] Allows to schedule **periodic** and **one-time** tasks on **EventBridge Scheduler**.\n*   [x] Simplifies creating, executing, and managing asynchronous task using SNS messages and Lambda events.\n*   [x] Includes `@decorators` in addition to `@app.decorators` for reusable apps.\n*   [x] Works well with any framework, interface,  toolkit... see [/templates](https://github.com/mongkok/seda/tree/main/templates).\n*   [x] Provides Serverless framework support via [plugin](https://github.com/mongkok/serverless-seda).\n*   [ ] Other event sources, e.g. CloudWatch, Kinesis, Dynamodb, SQS, S3...\n*   [ ] Easy to read documentation and tests.\n*   [ ] SAM templates and CDK support.\n\n## Installation\n\n```sh\npip install seda\n```\n\n## Example\n\n**main.py**:\n\n```py\nfrom datetime import datetime\n\nfrom seda import Seda\n\nseda = Seda()\n\n\n@seda.schedule(\"cron(* * * * ? *)\", args=(\"minutes\",))\nasync def myschedule(timespec: str = \"auto\") -\u003e None:\n    seda.log.info(f\"myschedule: {datetime.now().isoformat(timespec=timespec)}\")\n\n\n@seda.task\nasync def mytask(timespec: str = \"auto\") -\u003e None:\n    seda.log.info(f\"mytask: {datetime.now().isoformat(timespec=timespec)}\")\n```\n**`main.seda`** is an AWS Lambda handler in charge of managing the creation and execution of our tasks.\n\n*   **`@schedule`:** creates a new periodic \"schedule\" on EventBridge at deployment time.\n*   **`@task`:** creates one-time asynchronous tasks at runtime:\n    *   SNS messages: default\n    *   Lambda events:  `@task(service=\"lambda\")`\n    *   EventBridge one-time schedules: `mytask.at(\"...\")`\n\nFor reusable apps use `@task` and `@schedule` decorators that always points to the currently active `Seda` instance:\n\n**tasks.py**:\n\n```py\nfrom datetime import datetime\n\nfrom seda import task\n\n\n@task\nasync def mytask(timespec: str = \"auto\") -\u003e str:\n    return datetime.now().isoformat(timespec=timespec)\n```\n\n## Tasks\n\n```py\nawait mytask()\n```\n\n*   **SNS**: This task is executed asynchronously by sending a message to a previously subscribed SNS topic.\n*   **λ**: A second option is to directly invoke the Lambda function `InvocationType=Event` by adding the *\"service\"* option to the task decorator `@task(service=\"lambda\")`.\n*   **test**: For local and test environments the task is executed synchronously by default.\n\n## One-time schedules\n \n```py\nfrom datetime import datetime, timedelta\n\nmytask.at(datetime.now() + timedelta(minutes=5))\n```\n\nThe **`.at(datetime)`** method is equivalent to **`@schedule(\"at(datetime)\")`**.\n\nThese one-time schedules are created under a second EventBridge Schedule Group (group 1 -  N schedules) so after a new deployment we can clean the group of periodic schedules but keeping our one-time schedules.\n\n## `@schedule`\n\n| SEDA / AWS | TYPE | EXAMPLE |\n| ---------- | ---- | ------- |\n| expression\u003cbr /\u003e[ScheduleExpression](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-ScheduleExpression) | `str` | - `\"rate(5 minutes)\"`\u003cbr /\u003e- `\"cron(*/5 * * * ? *)\"`\u003cbr /\u003e- `\"at(2025-10-26T12:00:00)\"` |\n| args\u003cbr /\u003e- | `Optional[Sequence]` | `(\"a\", \"b\")` |\n| kwargs\u003cbr /\u003e- | `Optional[Dict]` | `{\"a\": \"b\"}` |\n| timezone\u003cbr /\u003e[ScheduleExpressionTimezone](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-ScheduleExpressionTimezone) | `Optional[str]` | `\"Asia/Saigon\"` |\n| time_window\u003cbr /\u003e[FlexibleTimeWindow](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-FlexibleTimeWindow) |`Optional[ScheduleTimeWindow]` | `{\"Mode\": \"FLEXIBLE\", \"MaximumWindowInMinutes\": 15}` |\n| retry_policy\u003cbr /\u003e[RetryPolicy](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_Target.html#scheduler-Type-Target-RetryPolicy) | `Optional[ScheduleRetryPolicy]` | `{\"MaximumEventAgeInSeconds\": 60, \"MaximumRetryAttempts\": 10}` |\n| start_date\u003cbr /\u003e[StartDate](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-StartDate) | `Optional[datetime]` | `datetime.now() + timedelta(minutes=5)` |\n| end_date\u003cbr /\u003e[EndDate](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-EndDate) | `Optional[datetime]` | `datetime.now() + timedelta(days=5)` |\n| dead_letter_arn\u003cbr /\u003e[DeadLetterConfig.Arn](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_Target.html#scheduler-Type-Target-DeadLetterConfig) | `Optional[str]` | `\"arn:aws:sqs:...\"` |\n| kms_key\u003cbr /\u003e[KmsKeyArn](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-KmsKeyArn) | `Optional[str]` | `\"arn:aws:kms:...\"` |\n\n## CLI\n\nSEDA CLI provides a list of commands to deploy, remove and debug SEDA resources on an **existing** Lambda function:\n\n```sh\nseda deploy --app main.seda -f myfunction\n```\n\n**Deploy `@schedule`, `@task`:**\n\n*   Creates the Schedule Groups for periodic and one-time tasks\n*   Creates N periodic schedules\n*   Creates SNS topic and a Lambda subscription to this topic\n*   Adds related IAM roles and policies\n\nA second deployment removes the periodic task Schedule Group and creates a new one adding the new schedules.\n\nWe can also remove the deployed stack:\n\n```sh\nseda remove --app main.seda -f myfunction\n```\n\n**Remote Function Invocation**\n\nInvoke Python interpreter:\n\n```sh\nseda python 'import sys;print(sys.version)' -f myfunction\n```\n\nRun shell commands:\n\n```sh\nseda shell env -f myfunction\n```\n\n## Serverless Framework\n\nThe plugin [serverless-seda](https://github.com/mongkok/serverless-seda) adds all SEDA CLI commands to Serverless framework CLI:\n\n```sh\nsls seda deploy\n```\n\n## ASGI\n\nSEDA seamlessly integrates with ASGI applications by adding [Mangum](https://github.com/jordaneremieff/mangum) handler to `seda[asgi]`.\n\n```sh\npip install seda[asgi]\n```\n\n**main.py**:\n\n```py\nfrom fastapi import FastAPI\nfrom seda import Seda\n\n\napp = FastAPI()\nseda = Seda(app)\n```\n\n## Default handler\n\nAdd any callable as a handler to process any non-SEDA events:\n\n```py\ndef myhandler(event, context):\n    pass\n\n\nseda = Seda(default_handler=myhandler)\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongkok%2Fseda","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmongkok%2Fseda","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmongkok%2Fseda/lists"}