seda


Nameseda JSON
Version 0.0.6 PyPI version JSON
download
home_pageNone
SummaryA Python toolkit to build Serverless Event-Driven Applications on AWS.
upload_time2023-01-11 01:49:19
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseNone
keywords aws event-driven scheduler serverless
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # SEDA

<p align="center">
    <em>A Python toolkit to build <b>S</b>erverless <b>E</b>vent-<b>D</b>riven <b>A</b>pplications on AWS.</em>
    <br><em>Documentation: <a href="https://seda.domake.io"><del>https://seda.domake.io</del></a> (pending)</em>
    <br><em><b>Examples: <a href="https://github.com/mongkok/seda/tree/main/templates">/templates</a></b></em>
</p>
<p align="center">
    <a href="https://github.com/mongkok/seda/actions">
        <img src="https://github.com/mongkok/seda/actions/workflows/test-suite.yml/badge.svg" alt="Test">
    </a>
    <a href="https://codecov.io/gh/mongkok/seda">
        <img src="https://img.shields.io/codecov/c/github/mongkok/seda?color=%2334D058" alt="Coverage">
    </a>
    <a href="https://www.codacy.com/gh/mongkok/seda/dashboard">
        <img src="https://app.codacy.com/project/badge/Grade/x" alt="Codacy">
    </a>
    <a href="https://pypi.org/project/seda">
        <img src="https://img.shields.io/pypi/v/seda" alt="Package version">
    </a>
</p>

## What

- [x] Allows to schedule **periodic** and **one-time** tasks on **EventBridge Scheduler**.
- [x] Simplifies creating, executing, and managing asynchronous task using SNS messages and Lambda events.
- [x] Includes `@decorators` in addition to `@app.decorators` for reusable apps.
- [x] Works well with any framework, interface,  toolkit... see [/templates](https://github.com/mongkok/seda/tree/main/templates).
- [x] Provides Serverless framework support via [plugin](https://github.com/mongkok/serverless-seda).
- [ ] Other event sources, e.g. CloudWatch, Kinesis, Dynamodb, SQS, S3...
- [ ] Easy to read documentation and tests.
- [ ] SAM templates and CDK support.

## Installation

```sh
pip install seda
```

## Example

**main.py**:

```py
from datetime import datetime

from seda import Seda

seda = Seda()


@seda.schedule("cron(* * * * ? *)", args=("minutes",))
async def myschedule(timespec: str = "auto") -> None:
    seda.log.info(f"myschedule: {datetime.now().isoformat(timespec=timespec)}")


@seda.task
async def mytask(timespec: str = "auto") -> None:
    seda.log.info(f"mytask: {datetime.now().isoformat(timespec=timespec)}")
```
**`main.seda`** is an AWS Lambda handler in charge of managing the creation and execution of our tasks.

- **`@schedule`:** creates a new periodic "schedule" on EventBridge at deployment time.
- **`@task`:** creates one-time asynchronous tasks at runtime:
    - SNS messages: default
    - Lambda events:  `@task(service="lambda")`
    - EventBridge one-time schedules: `mytask.at("...")`

For reusable apps use `@task` and `@schedule` decorators that always points to the currently active `Seda` instance:

**tasks.py**:

```py
from datetime import datetime

from seda import task


@task
async def mytask(timespec: str = "auto") -> str:
    return datetime.now().isoformat(timespec=timespec)
```

## Tasks

```py
await mytask()
```

- **SNS**: This task is executed asynchronously by sending a message to a previously subscribed SNS topic.
- **λ**: A second option is to directly invoke the Lambda function `InvocationType=Event` by adding the *"service"* option to the task decorator `@task(service="lambda")`.
- **test**: For local and test environments the task is executed synchronously by default.

## One-time schedules
 
```py
from datetime import datetime, timedelta

mytask.at(datetime.now() + timedelta(minutes=5))
```

The **`.at(datetime)`** method is equivalent to **`@schedule("at(datetime)")`**.

These 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.

## `@schedule`

| SEDA / AWS | TYPE | EXAMPLE |
| ---------- | ---- | ------- |
| expression<br />[ScheduleExpression](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-ScheduleExpression) | `str` | - `"rate(5 minutes)"`<br />- `"cron(*/5 * * * ? *)"`<br />- `"at(2025-10-26T12:00:00)"` |
| args<br />- | `Optional[Sequence]` | `("a", "b")` |
| kwargs<br />- | `Optional[Dict]` | `{"a": "b"}` |
| timezone<br />[ScheduleExpressionTimezone](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-ScheduleExpressionTimezone) | `Optional[str]` | `"Asia/Saigon"` |
| time_window<br />[FlexibleTimeWindow](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-FlexibleTimeWindow) |`Optional[ScheduleTimeWindow]` | `{"Mode": "FLEXIBLE", "MaximumWindowInMinutes": 15}` |
| retry_policy<br />[RetryPolicy](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_Target.html#scheduler-Type-Target-RetryPolicy) | `Optional[ScheduleRetryPolicy]` | `{"MaximumEventAgeInSeconds": 60, "MaximumRetryAttempts": 10}` |
| start_date<br />[StartDate](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-StartDate) | `Optional[datetime]` | `datetime.now() + timedelta(minutes=5)` |
| end_date<br />[EndDate](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-EndDate) | `Optional[datetime]` | `datetime.now() + timedelta(days=5)` |
| dead_letter_arn<br />[DeadLetterConfig.Arn](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_Target.html#scheduler-Type-Target-DeadLetterConfig) | `Optional[str]` | `"arn:aws:sqs:..."` |
| kms_key<br />[KmsKeyArn](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-KmsKeyArn) | `Optional[str]` | `"arn:aws:kms:..."` |

## CLI

SEDA CLI provides a list of commands to deploy, remove and debug SEDA resources on an **existing** Lambda function:

```sh
seda deploy --app main.seda -f myfunction
```

**Deploy `@schedule`, `@task`:**

- Creates the Schedule Groups for periodic and one-time tasks
- Creates N periodic schedules
- Creates SNS topic and a Lambda subscription to this topic
- Adds related IAM roles and policies

A second deployment removes the periodic task Schedule Group and creates a new one adding the new schedules.

We can also remove the deployed stack:

```sh
seda remove --app main.seda -f myfunction
```

**Remote Function Invocation**

Invoke Python interpreter:

```sh
seda python 'import sys;print(sys.version)' -f myfunction
```

Run shell commands:

```sh
seda shell env -f myfunction
```

## Serverless Framework

The plugin [serverless-seda](https://github.com/mongkok/serverless-seda) adds all SEDA CLI commands to Serverless framework CLI:

```sh
sls seda deploy
```

## ASGI

SEDA seamlessly integrates with ASGI applications by adding [Mangum](https://github.com/jordaneremieff/mangum) handler to `seda[asgi]`.

```sh
pip install seda[asgi]
```

**main.py**:

```py
from fastapi import FastAPI
from seda import Seda


app = FastAPI()
seda = Seda(app)
```

## Default handler

Add any callable as a handler to process any non-SEDA events:

```py
def myhandler(event, context):
    pass


seda = Seda(default_handler=myhandler)
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "seda",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "aws,event-driven,scheduler,serverless",
    "author": null,
    "author_email": "Dani <dani@domake.io>",
    "download_url": "https://files.pythonhosted.org/packages/d9/89/fb9453942300b91dd167999a86d2b808205c32e015805c04c0a5c062a8a7/seda-0.0.6.tar.gz",
    "platform": null,
    "description": "# SEDA\n\n<p align=\"center\">\n    <em>A Python toolkit to build <b>S</b>erverless <b>E</b>vent-<b>D</b>riven <b>A</b>pplications on AWS.</em>\n    <br><em>Documentation: <a href=\"https://seda.domake.io\"><del>https://seda.domake.io</del></a> (pending)</em>\n    <br><em><b>Examples: <a href=\"https://github.com/mongkok/seda/tree/main/templates\">/templates</a></b></em>\n</p>\n<p align=\"center\">\n    <a href=\"https://github.com/mongkok/seda/actions\">\n        <img src=\"https://github.com/mongkok/seda/actions/workflows/test-suite.yml/badge.svg\" alt=\"Test\">\n    </a>\n    <a href=\"https://codecov.io/gh/mongkok/seda\">\n        <img src=\"https://img.shields.io/codecov/c/github/mongkok/seda?color=%2334D058\" alt=\"Coverage\">\n    </a>\n    <a href=\"https://www.codacy.com/gh/mongkok/seda/dashboard\">\n        <img src=\"https://app.codacy.com/project/badge/Grade/x\" alt=\"Codacy\">\n    </a>\n    <a href=\"https://pypi.org/project/seda\">\n        <img src=\"https://img.shields.io/pypi/v/seda\" alt=\"Package version\">\n    </a>\n</p>\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\") -> None:\n    seda.log.info(f\"myschedule: {datetime.now().isoformat(timespec=timespec)}\")\n\n\n@seda.task\nasync def mytask(timespec: str = \"auto\") -> 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\") -> 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- **\u03bb**: 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<br />[ScheduleExpression](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-ScheduleExpression) | `str` | - `\"rate(5 minutes)\"`<br />- `\"cron(*/5 * * * ? *)\"`<br />- `\"at(2025-10-26T12:00:00)\"` |\n| args<br />- | `Optional[Sequence]` | `(\"a\", \"b\")` |\n| kwargs<br />- | `Optional[Dict]` | `{\"a\": \"b\"}` |\n| timezone<br />[ScheduleExpressionTimezone](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-ScheduleExpressionTimezone) | `Optional[str]` | `\"Asia/Saigon\"` |\n| time_window<br />[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<br />[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<br />[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<br />[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<br />[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<br />[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",
    "bugtrack_url": null,
    "license": null,
    "summary": "A Python toolkit to build Serverless Event-Driven Applications on AWS.",
    "version": "0.0.6",
    "split_keywords": [
        "aws",
        "event-driven",
        "scheduler",
        "serverless"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "50dae45b09cc912defdded713b097d31c131a249024781d37c13d15324fbdc21",
                "md5": "9b24177c8b1a57509390294ff560718f",
                "sha256": "6b3799f151dd2dc5e7419fca6491160bbd6db04779cc3a7df704a597b99b00c3"
            },
            "downloads": -1,
            "filename": "seda-0.0.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "9b24177c8b1a57509390294ff560718f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 23208,
            "upload_time": "2023-01-11T01:49:22",
            "upload_time_iso_8601": "2023-01-11T01:49:22.949320Z",
            "url": "https://files.pythonhosted.org/packages/50/da/e45b09cc912defdded713b097d31c131a249024781d37c13d15324fbdc21/seda-0.0.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d989fb9453942300b91dd167999a86d2b808205c32e015805c04c0a5c062a8a7",
                "md5": "c72bf7bb3f53194fd2faafb0fcd85d3a",
                "sha256": "5046d4145491f8f677b6368864beb914e28cd1bb18ce9dfe3f70a1c2d32509d0"
            },
            "downloads": -1,
            "filename": "seda-0.0.6.tar.gz",
            "has_sig": false,
            "md5_digest": "c72bf7bb3f53194fd2faafb0fcd85d3a",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 17352,
            "upload_time": "2023-01-11T01:49:19",
            "upload_time_iso_8601": "2023-01-11T01:49:19.227305Z",
            "url": "https://files.pythonhosted.org/packages/d9/89/fb9453942300b91dd167999a86d2b808205c32e015805c04c0a5c062a8a7/seda-0.0.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-01-11 01:49:19",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "lcname": "seda"
}
        
Elapsed time: 0.43235s