Skip to content

Commit a1f5cca

Browse files
committed
Initial code commit
0 parents  commit a1f5cca

File tree

20 files changed

+1526
-0
lines changed

20 files changed

+1526
-0
lines changed

.flake8

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
[flake8]
2+
# E203: Conflicts with black's formatting
3+
# E501: Conflicts with black's formatting, which defaults to a max
4+
# line length of 88 but will go over if necessary.
5+
# See https://github.com/ambv/black#line-length for more info
6+
# W605: Conflicts with regular expression formatting
7+
ignore = E203,E501,E731,W503,W605
8+
import-order-style = google
9+
# Packages added in this list should be added to the setup.cfg file as well
10+
application-import-names =
11+
sfn_workflow_client
12+
test_utils
13+
exclude =
14+
*vendor*
15+
.venv
16+
.env
17+
.pants.d
18+
.pantscache
19+
.git
20+
__init__.py
21+
setup.py

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
.DS_Store
2+
.venv*
3+
**/__pycache__/
4+
**/.cache/
5+
**/*.coverage
6+
**/*.egg-info
7+
**/*.pyc
8+
**/.tox
9+
**/dist

.pre-commit-config.yaml

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
default_stages: [commit]
3+
4+
default_language_version:
5+
python: python3
6+
7+
exclude: "examples/.*$"
8+
9+
repos:
10+
- repo: https://github.com/pre-commit/pre-commit-hooks
11+
rev: v2.4.0
12+
hooks:
13+
- id: check-ast
14+
- id: check-builtin-literals
15+
- id: check-byte-order-marker
16+
- id: check-executables-have-shebangs
17+
# Need to define stages explicitly since `default_stages` was not being respected
18+
stages: [commit]
19+
- id: check-merge-conflict
20+
- id: debug-statements
21+
- id: forbid-new-submodules
22+
- id: no-commit-to-branch
23+
- id: trailing-whitespace
24+
args: [--markdown-linebreak-ext=md]
25+
# Need to define stages explicitly since `default_stages` was not being respected
26+
stages: [commit]
27+
28+
- repo: local
29+
hooks:
30+
- id: isort
31+
name: Sort Python imports (isort)
32+
entry: isort
33+
language: python
34+
types: [file, python]
35+
additional_dependencies: [isort==4.3.16]
36+
37+
- id: black
38+
name: Format Python (black)
39+
entry: black
40+
language: python
41+
types: [file, python]
42+
additional_dependencies: [black==19.3b0]
43+
44+
- id: pydocstyle
45+
name: Lint Python docstrings (pydocstyle)
46+
entry: pydocstyle
47+
language: python
48+
types: [file, python]
49+
additional_dependencies: [pydocstyle==4.0.1]
50+
51+
- id: flake8
52+
name: Lint Python (flake8)
53+
entry: flake8 --config sfn-workflow-client/.flake8
54+
language: python
55+
types: [file, python]
56+
additional_dependencies:
57+
- flake8==3.7.9
58+
- "flake8-import-order<0.19,>=0.18"

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Copyright (c) 2020, Narrative Science
2+
3+
All rights reserved.
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9+
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
10+
- Neither the name of the <organization> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
11+
12+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
16+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
19+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

README.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# sfn-workflow-client
2+
3+
[![](https://img.shields.io/pypi/v/sfn-workflow-client.svg)](https://pypi.org/pypi/sfn-workflow-client/) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
4+
5+
Enhanced, asyncio-compatible client for AWS Step Functions.
6+
7+
Features:
8+
9+
- Trigger new executions
10+
- Query for state machine execution status
11+
- Wait for an execution to complete
12+
- Fetch execution history
13+
14+
- [Installation](#installation)
15+
- [Guide](#guide)
16+
- [Development](#development)
17+
18+
## Installation
19+
20+
sfn-workflow-client requires Python 3.6 or above.
21+
22+
```bash
23+
pip install sfn-workflow-client
24+
```
25+
26+
## Guide
27+
28+
```python
29+
from sfn_workflow_client.enums import ExecutionStatus
30+
from sfn_workflow_client.workflow import Workflow
31+
32+
# Initialize a workflow client
33+
workflow = Workflow("my-state-machine")
34+
# Fetch all executions
35+
collection = await workflow.executions.fetch()
36+
# Fetch currently running executions
37+
collection = await workflow.executions.fetch(status=ExecutionStatus.running)
38+
# Start a new execution
39+
execution = await workflow.executions.create().start()
40+
# Start a new execution and wait until it completes (useful for tests)
41+
execution = await workflow.executions.start_sync()
42+
# Find an execution by trace ID (for tests)
43+
execution = await workflow.executions.fetch().find_by_trace_id("abc")
44+
# Fetch the event history of an execution
45+
events = await execution.events.fetch()
46+
```
47+
48+
## Development
49+
50+
To develop sfn-workflow-client, install dependencies and enable the pre-commit hook:
51+
52+
```bash
53+
pip install pre-commit tox
54+
pre-commit install
55+
```
56+
57+
To run functional tests, you need to create an AWS IAM role with permissions to:
58+
59+
- Create/update/delete state machines
60+
- Start/stop executions
61+
62+
Set the following environment variables:
63+
64+
- `AWS_ACCOUNT_NUMBER`
65+
- `AWS_ACCESS_KEY_ID`
66+
- `AWS_SECRET_ACCESS_KEY`
67+
- `AWS_DEFAULT_REGION`
68+
- `AWS_IAM_ROLE_ARN`
69+
70+
To run tests:
71+
72+
```bash
73+
tox
74+
```

pyproject.toml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
[build-system]
2+
requires = ["flit_core >=2,<3"]
3+
build-backend = "flit_core.buildapi"
4+
5+
[tool.flit.metadata]
6+
module = "sfn_workflow_client"
7+
author = "Jonathan Drake"
8+
author-email = "[email protected]"
9+
home-page = "https://github.com/NarrativeScience/sfn-workflow-client"
10+
license = "BSD-3-Clause"
11+
description-file = "README.md"
12+
requires = [
13+
"aenum>=2.1.0,<3",
14+
"arrow>=0.12.1,<1",
15+
"backoff>=1.8.0,<2",
16+
"boto3",
17+
]
18+
classifiers = [
19+
"Intended Audience :: Developers",
20+
"License :: OSI Approved :: BSD License",
21+
"Programming Language :: Python :: 3",
22+
"Topic :: Software Development :: Libraries :: Python Modules",
23+
]
24+
requires-python = ">=3.6,<4"
25+
keywords = "aws step functions,workflow"
26+
27+
[tool.flit.sdist]
28+
include = ["LICENSE.md"]
29+
exclude = ["tests/"]

setup.cfg

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
[isort]
2+
# These rules should conform to flake8-import-order's google import order style
3+
# and black's styling rules
4+
# If adding a new package to this list, please make sure to update the .flake8 file as
5+
# well
6+
atomic=true
7+
combine_as_imports=true
8+
default_section=THIRDPARTY
9+
force_sort_within_sections=true
10+
include_trailing_comma=true
11+
known_standard_library=typing
12+
known_first_party=
13+
sfn_workflow_client
14+
test_utils
15+
line_length=88
16+
multi_line_output=3
17+
no_lines_before=LOCALFOLDER
18+
order_by_type=false
19+
sections=FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER
20+
skip=__init__.py
21+
22+
[pydocstyle]
23+
convention=numpy
24+
add-select=D413,D416,D417
25+
add-ignore=D202,D205,D400,D401,D406,D407
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
"""Enhanced, asyncio-compatible client for AWS Step Functions."""
2+
3+
__version__ = "0.1.0"

src/sfn_workflow_client/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
"""Constants and configuration for the workflow client"""
2+
import os
3+
4+
AWS_ACCOUNT_NUMBER = os.environ.get("AWS_ACCOUNT_NUMBER")

src/sfn_workflow_client/enums.py

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
"""Contains enums related to workflows and executions"""
2+
from aenum import UniqueEnum
3+
4+
5+
class ExecutionStatus(UniqueEnum):
6+
"""Workflow execution statuses"""
7+
8+
aborted = "ABORTED"
9+
failed = "FAILED"
10+
running = "RUNNING"
11+
succeeded = "SUCCEEDED"
12+
timed_out = "TIMED_OUT"
13+
14+
15+
# Set of statuses that indicate an execution completed
16+
COMPLETED_STATUSES = {
17+
ExecutionStatus.aborted,
18+
ExecutionStatus.failed,
19+
ExecutionStatus.succeeded,
20+
ExecutionStatus.timed_out,
21+
}
22+
23+
24+
class ExecutionEventType(UniqueEnum):
25+
"""Execution history event type."""
26+
27+
choice_state_entered = "ChoiceStateEntered"
28+
choice_state_exited = "ChoiceStateExited"
29+
execution_aborted = "ExecutionAborted"
30+
execution_failed = "ExecutionFailed"
31+
execution_started = "ExecutionStarted"
32+
execution_succeeded = "ExecutionSucceeded"
33+
execution_timed_out = "ExecutionTimedOut"
34+
fail_state_entered = "FailStateEntered"
35+
lambda_function_failed = "LambdaFunctionFailed"
36+
lambda_function_schedule_failed = "LambdaFunctionScheduleFailed"
37+
lambda_function_scheduled = "LambdaFunctionScheduled"
38+
lambda_function_start_failed = "LambdaFunctionStartFailed"
39+
lambda_function_started = "LambdaFunctionStarted"
40+
lambda_function_succeeded = "LambdaFunctionSucceeded"
41+
lambda_function_timed_out = "LambdaFunctionTimedOut"
42+
parallel_state_aborted = "ParallelStateAborted"
43+
parallel_state_entered = "ParallelStateEntered"
44+
parallel_state_exited = "ParallelStateExited"
45+
parallel_state_failed = "ParallelStateFailed"
46+
parallel_state_started = "ParallelStateStarted"
47+
parallel_state_succeeded = "ParallelStateSucceeded"
48+
pass_state_entered = "PassStateEntered"
49+
pass_state_exited = "PassStateExited"
50+
succeed_state_entered = "SucceedStateEntered"
51+
succeed_state_exited = "SucceedStateExited"
52+
task_failed = "TaskFailed"
53+
task_scheduled = "TaskScheduled"
54+
task_start_failed = "TaskStartFailed"
55+
task_started = "TaskStarted"
56+
task_state_aborted = "TaskStateAborted"
57+
task_state_entered = "TaskStateEntered"
58+
task_state_exited = "TaskStateExited"
59+
task_submit_failed = "TaskSubmitFailed"
60+
task_submitted = "TaskSubmitted"
61+
task_succeeded = "TaskSucceeded"
62+
task_timed_out = "TaskTimedOut"
63+
wait_state_aborted = "WaitStateAborted"
64+
wait_state_entered = "WaitStateEntered"
65+
wait_state_exited = "WaitStateExited"

0 commit comments

Comments
 (0)