Skip to content

Commit 5391936

Browse files
committed
setup with poetry
0 parents  commit 5391936

File tree

8 files changed

+353
-0
lines changed

8 files changed

+353
-0
lines changed

.github/workflows/ci.yml

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
9+
env:
10+
PYTHON_VERSION: 3.11
11+
12+
jobs:
13+
formatting:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Check out the code
17+
uses: actions/checkout@v3
18+
19+
- uses: actions/setup-python@v4
20+
with:
21+
python-version: ${{ env.PYTHON_VERSION }}
22+
23+
- name: Install poetry
24+
run: pip install poetry
25+
26+
- name: Determine dependencies
27+
run: poetry lock
28+
29+
- uses: actions/setup-python@v4
30+
with:
31+
python-version: ${{ env.PYTHON_VERSION }}
32+
cache: poetry
33+
34+
- name: Install Dependencies using Poetry
35+
run: poetry install
36+
37+
- name: Check formatting
38+
run: poetry run black --check .
39+
40+
linting:
41+
runs-on: ubuntu-latest
42+
steps:
43+
- name: Check out the code
44+
uses: actions/checkout@v3
45+
46+
- uses: actions/setup-python@v4
47+
with:
48+
python-version: ${{ env.PYTHON_VERSION }}
49+
50+
- name: Install poetry
51+
run: pip install poetry
52+
53+
- name: Determine dependencies
54+
run: poetry lock
55+
56+
- uses: actions/setup-python@v4
57+
with:
58+
python-version: ${{ env.PYTHON_VERSION }}
59+
cache: poetry
60+
61+
- name: Install Dependencies using Poetry
62+
run: poetry install
63+
64+
- name: Check code
65+
run: poetry run flake8
66+
67+
testing:
68+
runs-on: ubuntu-latest
69+
steps:
70+
- uses: actions/checkout@v3
71+
72+
- uses: actions/setup-python@v4
73+
with:
74+
python-version: ${{ env.PYTHON_VERSION }}
75+
76+
- name: Install poetry
77+
run: pip install poetry
78+
79+
- name: Determine dependencies
80+
run: poetry lock
81+
82+
- uses: actions/setup-python@v4
83+
with:
84+
python-version: ${{ env.PYTHON_VERSION }}
85+
cache: poetry
86+
87+
- name: Install dependencies
88+
run: poetry install
89+
90+
- name: Run pytest
91+
run: poetry run coverage run -m pytest tests/tests.py
92+
93+
- name: Run Coverage
94+
run: poetry run coverage report -m
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
name: PR
2+
on:
3+
pull_request_target:
4+
types:
5+
- opened
6+
- reopened
7+
- edited
8+
- synchronize
9+
10+
jobs:
11+
title-format:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: amannn/[email protected]
15+
env:
16+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/release-please.yml

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
on:
2+
push:
3+
branches:
4+
- main
5+
6+
name: release-please
7+
8+
env:
9+
PYTHON_VERSION: 3.11
10+
11+
jobs:
12+
release-please:
13+
runs-on: ubuntu-latest
14+
outputs:
15+
release_created: ${{ steps.release.outputs.release_created }}
16+
steps:
17+
- uses: GoogleCloudPlatform/release-please-action@v3
18+
id: release
19+
with:
20+
release-type: python
21+
package-name: snakemake-executor-plugin-dirac
22+
23+
publish:
24+
runs-on: ubuntu-latest
25+
needs: release-please
26+
if: ${{ needs.release-please.outputs.release_created }}
27+
steps:
28+
- uses: actions/checkout@v3
29+
30+
- uses: actions/setup-python@v4
31+
with:
32+
python-version: ${{ env.PYTHON_VERSION }}
33+
34+
- name: Install poetry
35+
run: pip install poetry
36+
37+
- name: Determine dependencies
38+
run: poetry lock
39+
40+
- uses: actions/setup-python@v4
41+
with:
42+
python-version: ${{ env.PYTHON_VERSION }}
43+
cache: poetry
44+
45+
- name: Install Dependencies using Poetry
46+
run: |
47+
poetry install
48+
49+
- name: Publish to PyPi
50+
env:
51+
PYPI_USERNAME: __token__
52+
PYPI_PASSWORD: ${{ secrets.PYPI_TOKEN }}
53+
run: poetry publish --build --username $PYPI_USERNAME --password $PYPI_PASSWORD

README.md

Whitespace-only changes.

pyproject.toml

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[build-system]
2+
requires = [ "poetry-core",]
3+
build-backend = "poetry.core.masonry.api"
4+
5+
[tool.poetry]
6+
name = "snakemake-executor-plugin-dirac"
7+
version = "0.1.0"
8+
description = ""
9+
authors = [ "jannisspeer <[email protected]>",]
10+
readme = "README.md"
11+
repository = "https://github.com/your/plugin"
12+
documentation = "https://snakemake.github.io/snakemake-plugin-catalog/plugins/executor/dirac.html"
13+
14+
[tool.poetry.dependencies]
15+
python = "^3.12"
16+
snakemake-interface-common = "^1.17.1"
17+
snakemake-interface-executor-plugins = "^9.0.0"
18+
19+
[tool.poetry.group.dev.dependencies]
20+
black = "^24.2.0"
21+
flake8 = "^7.0.0"
22+
coverage = "^7.4.3"
23+
pytest = "^8.1.1"
24+
snakemake = "^8.6.0"

setup.cfg

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
[flake8]
2+
# Recommend matching the black line length (default 88),
3+
# rather than using the flake8 default of 79:
4+
max-line-length = 88
5+
extend-ignore =
6+
# See https://github.com/PyCQA/pycodestyle/issues/373
7+
E203,
+143
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
from dataclasses import dataclass, field
2+
from typing import List, Generator, Optional
3+
from snakemake_interface_executor_plugins.executors.base import SubmittedJobInfo
4+
from snakemake_interface_executor_plugins.executors.remote import RemoteExecutor
5+
from snakemake_interface_executor_plugins.settings import (
6+
ExecutorSettingsBase,
7+
CommonSettings,
8+
)
9+
from snakemake_interface_executor_plugins.jobs import (
10+
JobExecutorInterface,
11+
)
12+
from snakemake_interface_common.exceptions import WorkflowError # noqa
13+
14+
15+
# Optional:
16+
# Define additional settings for your executor.
17+
# They will occur in the Snakemake CLI as --<executor-name>-<param-name>
18+
# Omit this class if you don't need any.
19+
# Make sure that all defined fields are Optional and specify a default value
20+
# of None or anything else that makes sense in your case.
21+
@dataclass
22+
class ExecutorSettings(ExecutorSettingsBase):
23+
myparam: Optional[int] = field(
24+
default=None,
25+
metadata={
26+
"help": "Some help text",
27+
# Optionally request that setting is also available for specification
28+
# via an environment variable. The variable will be named automatically as
29+
# SNAKEMAKE_<executor-name>_<param-name>, all upper case.
30+
# This mechanism should only be used for passwords and usernames.
31+
# For other items, we rather recommend to let people use a profile
32+
# for setting defaults
33+
# (https://snakemake.readthedocs.io/en/stable/executing/cli.html#profiles).
34+
"env_var": False,
35+
# Optionally specify a function that parses the value given by the user.
36+
# This is useful to create complex types from the user input.
37+
"parse_func": ...,
38+
# If a parse_func is specified, you also have to specify an unparse_func
39+
# that converts the parsed value back to a string.
40+
"unparse_func": ...,
41+
# Optionally specify that setting is required when the executor is in use.
42+
"required": True,
43+
},
44+
)
45+
46+
47+
# Required:
48+
# Specify common settings shared by various executors.
49+
common_settings = CommonSettings(
50+
# define whether your executor plugin executes locally
51+
# or remotely. In virtually all cases, it will be remote execution
52+
# (cluster, cloud, etc.). Only Snakemake's standard execution
53+
# plugins (snakemake-executor-plugin-dryrun, snakemake-executor-plugin-local)
54+
# are expected to specify False here.
55+
non_local_exec=True,
56+
# Whether the executor implies to not have a shared file system
57+
implies_no_shared_fs=True,
58+
# whether to deploy workflow sources to default storage provider before execution
59+
job_deploy_sources=True,
60+
# whether arguments for setting the storage provider shall be passed to jobs
61+
pass_default_storage_provider_args=True,
62+
# whether arguments for setting default resources shall be passed to jobs
63+
pass_default_resources_args=True,
64+
# whether environment variables shall be passed to jobs (if False, use
65+
# self.envvars() to obtain a dict of environment variables and their values
66+
# and pass them e.g. as secrets to the execution backend)
67+
pass_envvar_declarations_to_cmd=True,
68+
# whether the default storage provider shall be deployed before the job is run on
69+
# the remote node. Usually set to True if the executor does not assume a shared fs
70+
auto_deploy_default_storage_provider=True,
71+
# specify initial amount of seconds to sleep before checking for job status
72+
init_seconds_before_status_checks=0,
73+
)
74+
75+
76+
# Required:
77+
# Implementation of your executor
78+
class Executor(RemoteExecutor):
79+
def __post_init__(self):
80+
# access workflow
81+
self.workflow
82+
# access executor specific settings
83+
self.workflow.executor_settings
84+
85+
# IMPORTANT: in your plugin, only access methods and properties of
86+
# Snakemake objects (like Workflow, Persistence, etc.) that are
87+
# defined in the interfaces found in the
88+
# snakemake-interface-executor-plugins and the
89+
# snakemake-interface-common package.
90+
# Other parts of those objects are NOT guaranteed to remain
91+
# stable across new releases.
92+
93+
# To ensure that the used interfaces are not changing, you should
94+
# depend on these packages as >=a.b.c,<d with d=a+1 (i.e. pin the
95+
# dependency on this package to be at least the version at time
96+
# of development and less than the next major version which would
97+
# introduce breaking changes).
98+
99+
# In case of errors outside of jobs, please raise a WorkflowError
100+
101+
def run_job(self, job: JobExecutorInterface):
102+
# Implement here how to run a job.
103+
# You can access the job's resources, etc.
104+
# via the job object.
105+
# After submitting the job, you have to call
106+
# self.report_job_submission(job_info).
107+
# with job_info being of type
108+
# snakemake_interface_executor_plugins.executors.base.SubmittedJobInfo.
109+
# If required, make sure to pass the job's id to the job_info object, as keyword
110+
# argument 'external_job_id'.
111+
112+
...
113+
114+
async def check_active_jobs(
115+
self, active_jobs: List[SubmittedJobInfo]
116+
) -> Generator[SubmittedJobInfo, None, None]:
117+
# Check the status of active jobs.
118+
119+
# You have to iterate over the given list active_jobs.
120+
# If you provided it above, each will have its external_jobid set according
121+
# to the information you provided at submission time.
122+
# For jobs that have finished successfully, you have to call
123+
# self.report_job_success(active_job).
124+
# For jobs that have errored, you have to call
125+
# self.report_job_error(active_job).
126+
# This will also take care of providing a proper error message.
127+
# Usually there is no need to perform additional logging here.
128+
# Jobs that are still running have to be yielded.
129+
#
130+
# For queries to the remote middleware, please use
131+
# self.status_rate_limiter like this:
132+
#
133+
# async with self.status_rate_limiter:
134+
# # query remote middleware here
135+
#
136+
# To modify the time until the next call of this method,
137+
# you can set self.next_sleep_seconds here.
138+
...
139+
140+
def cancel_jobs(self, active_jobs: List[SubmittedJobInfo]):
141+
# Cancel all active jobs.
142+
# This method is called when Snakemake is interrupted.
143+
...

tests/tests.py

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
from typing import Optional
2+
import snakemake.common.tests
3+
from snakemake_interface_executor_plugins.settings import ExecutorSettingsBase
4+
5+
6+
# Check out the base classes found here for all possible options and methods:
7+
# https://github.com/snakemake/snakemake/blob/main/snakemake/common/tests/__init__.py
8+
class TestWorkflowsBase(snakemake.common.tests.TestWorkflowsBase):
9+
__test__ = True
10+
11+
def get_executor(self) -> str:
12+
return "dirac"
13+
14+
def get_executor_settings(self) -> Optional[ExecutorSettingsBase]:
15+
# instantiate ExecutorSettings of this plugin as appropriate
16+
...

0 commit comments

Comments
 (0)