$npx -y skills add Impertio-Studio/Frappe_Claude_Skill_Package --skill frappe-core-utilsUse when working with utility functions in Frappe v14-v16. Covers frappe.utils.* for date/time, number/money, string, validation, and file path operations. Prevents reinventing stdlib alternatives that break timezone awareness, locale formatting, or multi-tenancy. Keywords: frapp
| 1 | # Frappe Utility Functions |
| 2 | |
| 3 | ## Quick Reference: Python |
| 4 | |
| 5 | | Need | Function | Returns | |
| 6 | |------|----------|---------| |
| 7 | | Current date | `nowdate()` / `today()` | `datetime.date` | |
| 8 | | Current datetime | `now_datetime()` | `datetime.datetime` | |
| 9 | | Parse date string | `getdate(str)` | `datetime.date` | |
| 10 | | Parse datetime string | `get_datetime(str)` | `datetime.datetime` | |
| 11 | | Add days | `add_days(date, n)` | `datetime.date` | |
| 12 | | Add months | `add_months(date, n)` | `datetime.date` | |
| 13 | | Date difference | `date_diff(end, start)` | `int` (days) | |
| 14 | | Format for user | `format_date(dt)` | `str` (user locale) | |
| 15 | | Relative time | `pretty_date(dt)` | `str` ("2 hours ago") | |
| 16 | | Safe float | `flt(val, precision)` | `float` | |
| 17 | | Safe int | `cint(val)` | `int` | |
| 18 | | Safe string | `cstr(val)` | `str` | |
| 19 | | Safe bool | `sbool(val)` | `bool` | |
| 20 | | Safe division | `safe_div(a, b)` | `float` [v15+] | |
| 21 | | Money format | `fmt_money(amt, currency)` | `str` | |
| 22 | | Money in words | `money_in_words(amt, cur)` | `str` | |
| 23 | | Strip HTML | `strip_html(text)` | `str` | |
| 24 | | List to prose | `comma_and(items)` | `str` ("a, b, and c") | |
| 25 | | Validate email | `validate_email_address(e)` | `str` or `""` | |
| 26 | | Validate URL | `validate_url(url)` | `bool` | |
| 27 | | Parse JSON | `parse_json(s)` | `Any` | |
| 28 | | Files path | `get_files_path(is_private)` | `str` | |
| 29 | | Site path | `get_site_path(*parts)` | `str` | |
| 30 | | Unique list | `unique(seq)` | `list` | |
| 31 | | Hash | `generate_hash(s, length)` | `str` | |
| 32 | |
| 33 | > **ALL imports**: `from frappe.utils import nowdate, flt, ...` in controllers/whitelisted methods. |
| 34 | > In **Server Scripts**: Use `frappe.utils.nowdate()` directly — NO import statements allowed. |
| 35 | |
| 36 | --- |
| 37 | |
| 38 | ## Decision Tree: "Which function do I use?" |
| 39 | |
| 40 | ``` |
| 41 | Need a date/time value? |
| 42 | ├─ Current date → nowdate() or today() |
| 43 | ├─ Current datetime → now_datetime() |
| 44 | ├─ Parse a string → getdate() or get_datetime() |
| 45 | ├─ Add/subtract time → add_days(), add_months(), add_to_date() |
| 46 | ├─ Difference → date_diff() (days), month_diff(), time_diff_in_seconds() |
| 47 | ├─ Period boundary → get_first_day(), get_last_day(), get_quarter_start() |
| 48 | └─ Display to user → format_date(), format_datetime(), pretty_date() |
| 49 | |
| 50 | Need a number? |
| 51 | ├─ Convert safely → flt(), cint(), cstr(), sbool() |
| 52 | ├─ Round → rounded() (banker's rounding) |
| 53 | ├─ Safe divide → safe_div(a, b, default=0) [v15+] |
| 54 | ├─ Format money → fmt_money(amount, currency) |
| 55 | └─ Money to words → money_in_words(amount, currency) |
| 56 | |
| 57 | Need string processing? |
| 58 | ├─ HTML → strip_html(), escape_html(), is_html() |
| 59 | ├─ Join list → comma_and(), comma_or(), comma_sep() |
| 60 | ├─ Markdown ↔ HTML → to_markdown(), md_to_html() |
| 61 | └─ Mask sensitive → mask_string(input, show_first=4) [v16+] |
| 62 | |
| 63 | Need validation? |
| 64 | ├─ Email → validate_email_address(email, throw=False) |
| 65 | ├─ URL → validate_url(url, valid_schemes=["https"]) |
| 66 | ├─ Phone → validate_phone_number(phone, throw=False) |
| 67 | ├─ JSON → validate_json_string(s) |
| 68 | └─ IBAN → validate_iban(iban) [v16+] |
| 69 | |
| 70 | Need file/path? |
| 71 | ├─ Public files → get_files_path() |
| 72 | ├─ Private files → get_files_path(is_private=True) |
| 73 | ├─ Site directory → get_site_path("private", "backups") |
| 74 | ├─ Bench root → get_bench_path() |
| 75 | └─ File size → get_file_size(path, format=True) |
| 76 | ``` |
| 77 | |
| 78 | --- |
| 79 | |
| 80 | ## Critical Anti-Patterns |
| 81 | |
| 82 | ### NEVER use Python stdlib when frappe.utils exists |
| 83 | |
| 84 | | NEVER (stdlib) | ALWAYS (frappe.utils) | Why | |
| 85 | |----------------|----------------------|-----| |
| 86 | | `datetime.datetime.now()` | `now_datetime()` | Ignores system timezone | |
| 87 | | `datetime.date.today()` | `nowdate()` | Ignores system timezone | |
| 88 | | `float(val)` | `flt(val, precision)` | Crashes on None/empty | |
| 89 | | `int(val)` | `cint(val)` | Crashes on None/empty | |
| 90 | | `round(val, 2)` | `rounded(val, 2)` | Inconsistent rounding | |
| 91 | | `val1 / val2` | `safe_div(val1, val2)` | ZeroDivisionError [v15+] | |
| 92 | | `json.loads(s)` | `parse_json(s)` | Crashes on None/empty | |
| 93 | | `json.dumps(obj)` | `frappe.as_json(obj)` | Inconsistent serialization | |
| 94 | | `"{:,.2f}".format(a)` | `fmt_money(a, currency)` | Ignores locale/currency | |
| 95 | | `os.path.join(...)` | `get_site_path(...)` | Breaks multi-tenancy | |
| 96 | | `", ".join(items)` | `comma_and(items)` | No localized "and" | |
| 97 | | `dt.strftime(fmt)` | `format_date(dt)` | Ignores user preference | |
| 98 | | `re.sub(r'<.*?>', '', h)` | `strip_html(h)` | Misses edge cases | |
| 99 | |
| 100 | ### Server Script Sandbox |
| 101 | |
| 102 | ```python |
| 103 | # ❌ NEVER in Server Scripts |
| 104 | from frappe.utils import nowdate, flt |
| 105 | import json |
| 106 | |
| 107 | # ✅ ALWAYS in Server |