Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计通过

frappe-syntax-schedulerFrappe 语法调度器

Agent Skill

frappe-syntax-scheduler 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

588

周安装

24

GitHub Stars

87

下载量

188
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:frappe-syntax-scheduler(Frappe 语法调度器)
来源仓库:https://github.com/openaec-foundation/erpnext_anthropic_claude_development_skill_package
仓库路径:skills/frappe-syntax-scheduler
安装命令:
npx skills add https://github.com/openaec-foundation/erpnext_anthropic_claude_development_skill_package --skill frappe-syntax-scheduler
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/openaec-foundation/erpnext_anthropic_claude_development_skill_package --skill frappe-syntax-scheduler

简介

用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中围绕仓库状态或协作事项进行整理。
  • 通过 npx skills add 命令从指定仓库安装,需确认权限和维护状态。
  • 使用前建议核实是否会触发联网、命令执行或文件读写操作。
  • frappe-syntax-scheduler 属于开发类 Skill,可作为该场景下的辅助能力补充。

SKILL.md

Frappe Scheduler & Background Jobs

Deterministic syntax reference for Frappe scheduler events and background job processing via Redis Queue (RQ).

Decision Tree

Need periodic execution?
├─ Fixed interval (hourly/daily/weekly/monthly) → scheduler_events in hooks.py
├─ Custom cron schedule → scheduler_events.cron in hooks.py
├─ User-configurable interval → Scheduled Job Type DocType
└─ No, triggered by user/event
   ├─ Run method on a specific document → frappe.enqueue_doc()
   ├─ Run standalone function async → frappe.enqueue()
   └─ Run from controller on self → self.queue_action()

Quick Reference: Scheduler Events (hooks.py)

# hooks.py — ALWAYS run bench migrate after changes
scheduler_events = {
    # Standard events (default queue)
    "all": ["myapp.tasks.every_tick"],           # Every tick [v14: 240s, v15+: 60s]
    "hourly": ["myapp.tasks.hourly_task"],
    "daily": ["myapp.tasks.daily_task"],
    "weekly": ["myapp.tasks.weekly_task"],
    "monthly": ["myapp.tasks.monthly_task"],

    # Long queue events (for heavy processing)
    "hourly_long": ["myapp.tasks.hourly_heavy"],
    "daily_long": ["myapp.tasks.daily_heavy"],
    "weekly_long": ["myapp.tasks.weekly_heavy"],
    "monthly_long": ["myapp.tasks.monthly_heavy"],

    # Cron events (croniter-compatible syntax)
    "cron": {
        "*/15 * * * *": ["myapp.tasks.every_15_min"],
        "0 9 * * 1-5": ["myapp.tasks.weekday_9am"],
        "0 0 1 * *": ["myapp.tasks.first_of_month"],
    }
}

CRITICAL: ALWAYS run bench migrate after ANY change to scheduler_events. Without it, changes are NOT applied.

Scheduler Event Types

EventFrequencyQueueUse Case
allEvery tick [v14: 4min, v15+: 60s]defaultFrequent polling
hourlyOnce per hourdefaultSync, cleanup
dailyOnce per daydefaultReports, summaries
weeklyOnce per weekdefaultArchival
monthlyOnce per monthdefaultBilling, statements
hourly_longOnce per hourlongHeavy sync
daily_longOnce per daylongLarge exports
weekly_longOnce per weeklongData warehousing
monthly_longOnce per monthlongAnnual reports
cronCustom scheduleconfigurableAny custom timing

Cron Syntax

┌───────────── minute (0-59)
│ ┌───────────── hour (0-23)
│ │ ┌───────────── day of month (1-31)
│ │ │ ┌───────────── month (1-12)
│ │ │ │ ┌───────────── day of week (0-6, Sunday=0)
│ │ │ │ │
* * * * *
SymbolMeaningExample
*Any value* * * * * = every minute
,List1,15 * * * * = minute 1 and 15
-Range0 9-17 * * * = hours 9 through 17
/Interval*/10 * * * * = every 10 minutes

Common patterns:

  • Every 5 min: */5 * * * *
  • Weekdays at 9:00: 0 9 * * 1-5
  • Monday at 8:00: 0 8 * * 1
  • Business hours hourly: 0 9-17 * * 1-5

Quick Reference: frappe.enqueue()

frappe.enqueue(
    method,                      # REQUIRED: function or "dotted.module.path"
    queue="default",             # "short", "default", "long", or custom
    timeout=None,                # Override queue timeout (seconds)
    is_async=True,               # False = run synchronously (skip worker)
    now=False,                   # True = run via frappe.call() directly
    job_id=None,                 # [v15+] Unique ID for deduplication
    enqueue_after_commit=False,  # Wait for DB commit before enqueue
    at_front=False,              # Place at front of queue
    on_success=None,             # Success callback
    on_failure=None,             # Failure callback
    **kwargs                     # Arguments passed to method
)

Queue Types

QueueDefault TimeoutUse When
short300s (5 min)Task < 30 seconds
default300s (5 min)Task 30s - 5 min
long1500s (25 min)Task 5 - 25 min
long + custom timeoutuser-definedTask > 25 min
# Short queue — quick status update
frappe.enqueue("myapp.tasks.update_status", queue="short", doc=doc.name)

# Long queue — heavy report generation
frappe.enqueue("myapp.tasks.generate_report", queue="long", timeout=3600)

frappe.enqueue_doc()

Enqueue a controller method on a specific document.

frappe.enqueue_doc(
    "Sales Invoice",              # DocType
    "SINV-00001",                 # Document name
    "send_notification",          # Controller method name
    queue="long",
    timeout=600,
    recipient="user@example.com"  # kwargs passed to method
)

The controller method MUST be decorated with @frappe.whitelist():

class SalesInvoice(Document):
    @frappe.whitelist()
    def send_notification(self, recipient):
        # self is the loaded document
        pass

self.queue_action()

Alternative from within a controller:

class SalesOrder(Document):
    def on_submit(self):
        self.queue_action("send_emails", emails=email_list)

    def send_emails(self, emails):
        for email in emails:
            send_mail(email)

Job Deduplication

[v15+] Recommended Pattern

from frappe.utils.background_jobs import is_job_enqueued

job_id = f"import::{doc.name}"
if not is_job_enqueued(job_id):
    frappe.enqueue(
        "myapp.tasks.import_data",
        job_id=job_id,
        doc_name=doc.name
    )
else:
    frappe.msgprint("Import already in progress")

[v14] Legacy Pattern (NEVER use in new code)

from frappe.core.page.background_jobs.background_jobs import get_info
enqueued = [d.get("job_name") for d in get_info()]
if name not in enqueued:
    frappe.enqueue(..., job_name=name)

Error Handling Pattern

ALWAYS use try/except with commit/rollback per record in batch jobs:

def process_records(records):
    success, errors = 0, 0
    for record in records:
        try:
            process_single(record)
            frappe.db.commit()
            success += 1
        except Exception:
            frappe.db.rollback()
            frappe.log_error(
                frappe.get_traceback(),
                f"Process Error: {record}"
            )
            errors += 1
    return {"success": success, "errors": errors}

Retry Pattern

def task_with_retry(data, retry_count=0, max_retries=3):
    try:
        external_api_call(data)
    except Exception:
        if retry_count < max_retries:
            frappe.enqueue(
                "myapp.tasks.task_with_retry",
                queue="default",
                data=data,
                retry_count=retry_count + 1,
                max_retries=max_retries,
                enqueue_after_commit=True
            )
            frappe.log_error(f"Retry {retry_count+1}/{max_retries}", "Task Retry")
        else:
            frappe.log_error(frappe.get_traceback(), f"Failed after {max_retries} retries")
            raise

Callbacks

def on_success_handler(job, connection, result, *args, **kwargs):
    frappe.publish_realtime("show_alert", {"message": "Done!"})

def on_failure_handler(job, connection, type, value, traceback):
    frappe.log_error(f"Job {job.id} failed: {value}", "Job Error")

frappe.enqueue(
    "myapp.tasks.risky_task",
    on_success=on_success_handler,
    on_failure=on_failure_handler,
)

Progress Updates

def long_task(items, user):
    total = len(items)
    for i, item in enumerate(items):
        process_item(item)
        frappe.publish_realtime(
            "task_progress",
            {"progress": (i + 1) / total * 100, "current": i + 1, "total": total},
            user=user,
        )

User Context

CRITICAL: Scheduler jobs run as Administrator. ALWAYS set explicit ownership when creating documents:

def scheduled_task():
    doc = frappe.new_doc("ToDo")
    doc.owner = "user@example.com"
    doc.insert(ignore_permissions=True)

Monitoring

ToolPurpose
bench doctorScheduler status, worker health
RQ Worker (DocType)Worker status: busy/idle
RQ Job (DocType)Job status, queue filtering
Scheduled Job Log (DocType)Execution history, errors
logs/worker.error.logWorker exceptions
logs/scheduler.logScheduler activity

Version Differences

Featurev14v15+
Tick interval (all event)~240s (4 min)~60s
Config key for tickscheduler_intervalscheduler_tick_interval
Deduplicationjob_name (deprecated)job_id + is_job_enqueued()

Custom tick in common_site_config.json:

{ "scheduler_tick_interval": 120 }

Critical Rules

  1. ALWAYS run bench migrate after any scheduler_events change in hooks.py
  2. ALWAYS use job_id + is_job_enqueued() for deduplication [v15+]
  3. ALWAYS choose the correct queue: short/default/long based on task duration
  4. ALWAYS commit per record and rollback on error in batch jobs
  5. ALWAYS remember that scheduler jobs run as Administrator
  6. NEVER run heavy logic directly in a scheduler event — enqueue it instead
  7. NEVER use job_name for deduplication in new code (v14 legacy)

Reference Files

See Also

  • frappe-syntax-hooks — Full hooks.py reference
  • frappe-core-background — Background job architecture
  • frappe-errors-jobs — Job failure debugging

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

33.59%
按下载量换算63

Claude

31.95%
按下载量换算60

Cursor

21.54%
按下载量换算40

Gemini CLI

9.62%
按下载量换算18

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills