Skip to main content

spakky-task

Spakky Framework를 위한 태스크 큐 추상화 레이어입니다. @task와 @schedule metadata를 backend plugin이 실행 가능한 task route로 변환하게 합니다.

설치

pip install spakky-task

주요 기능

  • @TaskHandler stereotype: 클래스를 task handler pod로 표시합니다.
  • @task decorator: 메서드를 on-demand dispatch 가능한 task로 표시합니다.
  • @schedule decorator: 메서드를 주기 실행 대상(interval, daily, crontab)으로 표시합니다.
  • Crontab value object: Weekday/Month enum을 사용하는 Python-native cron 명세
  • Post-processor: @TaskHandler pod에서 task route를 자동 스캔하고 등록합니다.
  • 직접 실행: 같은 프로세스에서 task를 실행할 때 기존 request-scope context를 유지합니다.
  • 구현체 중립: 플러그인을 통해 Celery 등 임의의 태스크 큐 백엔드와 동작

사용법

On-demand 태스크

@task는 메서드를 on-demand dispatch 대상으로 표시합니다. 백엔드 플러그인(예: spakky-celery)은 AOP로 호출을 가로채 task queue로 라우팅합니다.

from spakky.task import TaskHandler, task


@TaskHandler()
class EmailTaskHandler:
    @task
    def send_email(self, to: str, subject: str, body: str) -> None:
        """Dispatched to the task queue when called."""
        ...

예약 태스크

@schedule는 메서드를 주기 실행 대상으로 표시합니다. interval, at, crontab 중 정확히 하나를 지정해야 합니다.

from datetime import time, timedelta

from spakky.task import TaskHandler, Crontab, Weekday, schedule


@TaskHandler()
class MaintenanceHandler:
    @schedule(interval=timedelta(minutes=30))
    def health_check(self) -> None:
        """Runs every 30 minutes."""
        ...

    @schedule(at=time(3, 0))
    def daily_cleanup(self) -> None:
        """Runs daily at 03:00."""
        ...

    @schedule(crontab=Crontab(weekday=Weekday.MONDAY, hour=9))
    def weekly_report(self) -> None:
        """Runs every Monday at 09:00."""
        ...

Crontab 명세

Crontab은 cron 문자열 대신 Python-native 타입을 사용합니다. None은 "every"(wildcard)를 의미합니다.

from spakky.task import Crontab, Weekday, Month

# Every Monday at 03:00
Crontab(weekday=Weekday.MONDAY, hour=3)

# Mon/Wed/Fri at 09:00
Crontab(weekday=(Weekday.MONDAY, Weekday.WEDNESDAY, Weekday.FRIDAY), hour=9)

# 1st and 15th of every month at midnight
Crontab(day=(1, 15))

# Every January 1st at midnight
Crontab(month=Month.JANUARY, day=1)

필드 순서(시간 단위가 큰 것부터):

필드 타입 기본값
month Month | tuple[Month, ...] | None None(every)
day int | tuple[int, ...] | None None(every)
weekday Weekday | tuple[Weekday, ...] | None None(every)
hour int 0
minute int 0

Task route 접근

from spakky.task import TaskRegistrationPostProcessor

post_processor = container.get(TaskRegistrationPostProcessor)
routes = post_processor.get_task_routes()
# {<bound method send_email>: TaskRoute(), ...}

인증 metadata와 직접 실행

@task는 spakky-auth의 보호 decorator와 함께 사용할 수 있습니다. Task route는 보호 요구사항 metadata를 보존하며, 직접 실행은 현재 ApplicationContext의 request-scope 값을 그대로 사용합니다. 같은 프로세스에서 실행되는 task는 AuthContextSnapshot이 필요하지 않고, 보호된 task도 AuthContext를 메서드 인자로 받을 필요가 없습니다.

from spakky.auth import protected, require_auth_context
from spakky.core.pod.interfaces.application_context import IApplicationContext
from spakky.task import DirectTaskExecutor, DirectTaskInvocation, TaskHandler, task


@TaskHandler()
class ReportTaskHandler:
    def __init__(self, application_context: IApplicationContext) -> None:
        self._application_context = application_context

    @task
    @protected
    def generate(self) -> str:
        return require_auth_context(self._application_context).subject.id


application_context: IApplicationContext = ...
executor = DirectTaskExecutor()
executor.set_application_context(application_context)
result = executor.execute(
    DirectTaskInvocation(
        handler_type=ReportTaskHandler,
        method_name="generate",
    )
)

구성 요소

구성 요소 설명
TaskHandler 태스크 핸들러 클래스용 stereotype decorator
@task on-demand 태스크 dispatch용 메서드 decorator
@schedule 주기 실행용 메서드 decorator(interval, at, crontab)
TaskRoute @task 메서드용 annotation
ScheduleRoute @schedule 메서드용 annotation
Crontab cron 유사 schedule 명세용 frozen dataclass
Weekday 요일용 IntEnum(Monday=0 ... Sunday=6)
Month 월용 IntEnum(January=1 ... December=12)
DirectTaskExecutor request-scope context를 유지하는 같은 프로세스 task 실행기
DirectTaskInvocation 직접 실행 대상 handler/method/argument metadata
TaskRegistrationPostProcessor @TaskHandler pod를 스캔하고 @task 메서드를 수집

에러

에러 설명
TaskNotFoundError registry에서 task reference를 찾을 수 없음
DuplicateTaskError 이미 등록된 task를 다시 등록하려는 경우
InvalidScheduleSpecificationError @schedule called with zero or multiple schedule options

관련 패키지

  • spakky-celery: AOP 기반 task dispatch와 schedule 등록을 위한 Celery backend

개발 검증

패키지 단위 검증은 해당 패키지 디렉토리에서 실행합니다.

uv run ruff format .
uv run ruff check .
uv run pyrefly check
uv run pytest

pytest는 각 패키지 pyproject.toml의 coverage 설정을 사용합니다.

라이선스

MIT License

Metadata

Release files for spakky-task 8.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spakky-task 8.1.0
File Size Uploaded
spakky_task-8.1.0.tar.gz 9.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for spakky-task 8.1.0
File Interpreter ABI Platform
spakky_task-8.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 22.8 kB

Release files / spakky_task-8.1.0.tar.gz

Download URL spakky_task-8.1.0.tar.gz
Size 9.5 kB
Tags Source
SHA-256 checksum
How to use checksums
23b71ca2d80bf1cccda713b0690503e9246d56b08b83ef7b8b4304e9dafc6e61
BLAKE2b-256 checksum
How to use checksums
1c7b3a82d036b1e289a18a63a94fc179efd7ec7293d9ba38741b804a73e5d834
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release files / spakky_task-8.1.0-py3-none-any.whl

Download URL spakky_task-8.1.0-py3-none-any.whl
Size 13.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
253bd0e130d8a3f38df91d4dd70702ba15d2996fcdb082ec6317f45e741486b2
BLAKE2b-256 checksum
How to use checksums
96f64c2c6bd6cf8e36da47a91e6b06b54192e9ad0fcd6b2fc621b2c9d0e627f5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 22, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

8.1.0 This release

2 release files

8.0.0

2 release files

7.2.0

2 release files

7.1.1

2 release files

7.1.0

2 release files

7.0.0

2 release files

6.13.0

2 release files

6.12.0

2 release files

6.11.0

2 release files

6.10.1

2 release files

6.10.0

2 release files

6.9.1

2 release files

6.9.0

2 release files

6.8.0

2 release files

6.7.0

2 release files

6.6.1

2 release files

6.6.0

2 release files

6.5.0

2 release files

6.4.0

2 release files

6.3.1

2 release files

6.3.0

2 release files

6.2.0

2 release files

6.1.3

2 release files

6.1.2

2 release files

6.1.1

2 release files

6.1.0

2 release files

6.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page