Documentation Frappe Framework

Frappe Framework

Fonctions utilitaires

Les fonctions utilitaires que Frappe fournit dans frappe.utils pour manipuler dates et durées, formater, valider, générer des PDF, utiliser le cache Redis, envoyer des e-mails et plus.

11 min de lectureMis à jour le Source : docs.frappe.io

Présentation

Frappe Framework fournit de nombreuses fonctions utilitaires pour les opérations courantes : gestion des dates et heures propres au site, formatage des dates et des devises, génération de PDF, et bien d’autres.

Ces fonctions s’importent depuis le module frappe.utils (et ses sous-modules comme frappe.utils.logger et frappe.utils.data) dans n’importe quel fichier Python de votre app Frappe. La liste ci-dessous n’est pas exhaustive : parcourez le code source du framework pour découvrir tout ce qui existe.

Dates et heures

now

now()

Renvoie la date et l’heure courantes au format yyyy-mm-dd hh:mm:ss.

python
from frappe.utils import now

now() # '2021-05-25 06:38:52.242515'

getdate

getdate(string_date=None)

Convertit string_date (au format yyyy-mm-dd) en objet datetime.date. Sans argument, renvoie la date du jour. Lève une exception si string_date n’est pas une date valide.

python
from frappe.utils import getdate

getdate() # datetime.date(2021, 5, 25)
getdate('2000-03-18') # datetime.date(2000, 3, 18)

today

today()

Renvoie la date du jour au format yyyy-mm-dd.

python
from frappe.utils import today

today() # '2021-05-25'

add_to_date

add_to_date(date, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0, as_string=False, as_datetime=False)

ParamètreRôle
dateChaîne ou objet datetime ; si None, la fonction utilise le datetime courant.
as_stringRenvoie le résultat sous forme de chaîne.
as_datetimeSi as_string et as_datetime valent tous deux True, renvoie une chaîne datetime ; sinon seulement la chaîne date.

Cette fonction est pratique pour calculer des écarts de date ou d’heure, par exemple ajouter ou retrancher un certain nombre de jours à une date donnée.

python
from datetime import datetime # from python std library
from frappe.utils import add_to_date

today = datetime.now().strftime('%Y-%m-%d')
print(today) # '2021-05-21'

after_10_days = add_to_date(datetime.now(), days=10, as_string=True)
print(after_10_days) # '2021-05-31'

add_to_date(datetime.now(), months=2) # datetime.datetime(2021, 7, 21, 15, 31, 18, 119999)
add_to_date(datetime.now(), days=10, as_string=True, as_datetime=True) # '2021-05-31 15:30:23.757661'
add_to_date(None, years=6) # datetime.datetime(2027, 5, 21, 15, 32, 31, 652089)

date_diff

date_diff(date_2, date_1)

Renvoie la différence entre les deux dates, en jours.

python
from frappe.utils import add_to_date, today, date_diff
date_1 = today()
date_2 = add_to_date(date_1, days=10)

print(date_diff(date_2, date_1)) #10

days_diff

days_diff(date_2, date_1)

Renvoie la différence entre les deux dates, en jours.

python
from frappe.utils import add_to_date, today, days_diff
date_1 = today()
date_2 = add_to_date(date_1, days=10)

print(days_diff(date_2, date_1)) #10

month_diff

month_diff(date_2, date_1)

Renvoie la différence entre les deux dates, en mois.

python
from frappe.utils import add_to_date, month_diff
date_1 = "2024-07-01"
date_2 = add_to_date(date_1, days=60)

print(month_diff(date_2, date_1)) #2

pretty_date

pretty_date(iso_datetime)

Prend une date-heure ISO et renvoie une chaîne qui indique depuis combien de temps elle est passée. Très courant dans les applications de communication, comme les messageries instantanées.

python
from frappe.utils import pretty_date, now, add_to_date

pretty_date(now()) # 'just now'

# Some example outputs:

# 1 hour ago
# 20 minutes ago
# 1 week ago
# 5 years ago

format_duration

format_duration(seconds, hide_days=False)

Convertit une durée en secondes (flottant) en un format de durée lisible.

python
from frappe.utils import format_duration

format_duration(50) # '50s'
format_duration(10000) # '2h 46m 40s'
format_duration(1000000) # '11d 13h 46m 40s'

# Convert days to hours
format_duration(1000000, hide_days=True) # '277h 46m 40s'

Formatage de texte et de montants

comma_and

comma_and(some_list, add_quotes=True)

À partir d’une liste ou d’un tuple some_list, renvoie une chaîne au format 1er élément, 2e élément, … and dernier élément. La fonction utilise frappe._, vous n’avez donc pas à vous soucier de la traduction du mot and. Si add_quotes vaut False, les éléments sont renvoyés sans guillemets ; avec guillemets sinon. Si some_list n’est ni une liste ni un tuple, il est renvoyé tel quel.

python
from frappe.utils import comma_and

comma_and([1, 2, 3]) # "'1', '2' and '3'"
comma_and(['Apple', 'Ball', 'Cat'], add_quotes=False) # 'Apple, Ball and Cat'
comma_and('abcd') # 'abcd'

> [!NOTE] > Il existe aussi une fonction comma_or, identique à comma_and à l’exception du séparateur, qui est or.

money_in_words

money_in_words(number, main_currency=None, fraction_currency=None)

ParamètreRôle
numberMontant monétaire (flottant).
main_currencyDevise principale. Si elle n’est pas fournie, la fonction la cherche dans les paramètres par défaut, puis utilise INR à défaut.
fraction_currencyNom de la sous-unité monétaire.

Renvoie le montant en toutes lettres, avec la devise et la sous-unité.

python
from frappe.utils import money_in_words

money_in_words(900) # 'INR Nine Hundred and Fifty Paisa only.'
money_in_words(900.50) # 'INR Nine Hundred and Fifty Paisa only.'
money_in_words(900.50, 'USD') # 'USD Nine Hundred and Fifty Centavo only.'
money_in_words(900.50, 'USD', 'Cents') # 'USD Nine Hundred and Fifty Cents only.'

get_abbr

get_abbr(string, max_len=2)

Renvoie une abréviation (initiales seulement) de string, limitée à max_len lettres. Très utilisée dans Frappe Framework et ERPNext pour générer des vignettes ou des images de substitution.

python
from frappe.utils import get_abbr

get_abbr('Gavin') # 'G'
get_abbr('Coca Cola Company') # 'CC'
get_abbr('Mohammad Hussain Nagaria', max_len=3) # 'MHN'

mask_string

mask_string(input_string, mask_char="*", show_first=4, show_last=3)

Masque une chaîne pour protéger la confidentialité : les caractères du milieu sont cachés, tandis qu’un nombre configurable de caractères au début et à la fin reste visible pour l’identification.

python
from frappe.utils import mask_string

mask_string("1234567890")  # "1234***890"
mask_string("12345")       # "******"
mask_string("1234567890", mask_char="#", show_first=2, show_last=2)  # "12####90"

random_string

random_string(length)

Génère une chaîne aléatoire de length caractères. Utile dans certains cas pour la cryptographie ou la génération de secrets.

python
from frappe.utils import random_string

random_string(40) # 'mcrLCrlvkUdkaOe8m5xMI8IwDB8lszwJsWtZFveQ'
random_string(6) # 'htrB4L'
random_string(6) #'HNRirG'

unique

unique(seq)

seq : un itérable ou une séquence.

Renvoie la liste des éléments de la séquence sans les doublons, en conservant l’ordre, contrairement à list(set(seq)).

python
from frappe.utils import unique

unique([1, 2, 3, 1, 1, 1]) # [1, 2, 3]
unique('abcda') # ['a', 'b', 'c', 'd']
unique(('Apple', 'Apple', 'Banana', 'Apple')) # ['Apple', 'Banana']

Validation

validate_json_string

validate_json_string(string)

Lève frappe.ValidationError si string n’est pas une chaîne JSON (JavaScript Object Notation) valide, comme le montre l’exemple ci-dessous. Vous pouvez entourer l’appel d’un bloc try-except pour gérer l’erreur.

python
import frappe
from frappe.utils import validate_json_string

# No Exception thrown
validate_json_string('[]')
validate_json_string('[{}]')
validate_json_string('[{"player": "one", "score": 199}]')

try:
    # Throws frappe.ValidationError
    validate_json_string('invalid json')
except frappe.ValidationError:
    print('Not a valid JSON string')

validate_url

validate_url(txt, throw=False, valid_schemes=None)

ParamètreRôle
txtChaîne dont on vérifie la validité.
throwLever une exception si txt n’est pas une URL valide ; False par défaut.
valid_schemesChaîne ou itérable (liste, tuple ou ensemble). Si fourni, le schéma de l’URL est vérifié par rapport à cette valeur.

Vérifie qu’une chaîne représente une adresse URL valide.

python
from frappe.utils import validate_url

validate_url('google') # False
validate_url('https://google.com') # True
validate_url('https://google.com', throw=True) # throws ValidationError

validate_email_address

validate_email_address(email_str, throw=False)

Renvoie une chaîne contenant l’adresse e-mail, ou la liste séparée par des virgules des adresses e-mail valides, présentes dans email_str. Si throw vaut True, frappe.InvalidEmailAddressError est levée quand la chaîne ne contient aucune adresse valide ; sinon une chaîne vide est renvoyée.

python
from frappe.utils import validate_email_address

# Single valid email address
validate_email_address('[email protected]') # '[email protected]'
validate_email_address('other text, [email protected], some other text') # '[email protected]'

# Multiple valid email address
validate_email_address(
    'some text, [email protected], some other text, [email protected], yet another no-emailic phrase.'
) # '[email protected], [email protected]'

# Invalid email address
validate_email_address('some other text') # ''

validate_phone_number

validate_phone_number(phone_number, throw=False)

Renvoie True si phone_number (chaîne) est un numéro de téléphone valide. Si le numéro est invalide et que throw vaut True, frappe.InvalidPhoneNumberError est levée.

python
from frappe.utils import validate_phone_number

# Valid phone numbers
validate_phone_number('753858375') # True
validate_phone_number('+91-75385837') # True

# Invalid phone numbers
validate_phone_number('invalid') # False
validate_phone_number('87345%%', throw=True) # InvalidPhoneNumberError

PDF

get_pdf

get_pdf(html, options=None, output=None)

ParamètreRôle
htmlChaîne HTML à rendre.
optionsdict de configuration, facultatif.
outputObjet PdfFileWriter, facultatif.

Cette fonction s’appuie sur les modules pdfkit et pyPDF2 pour générer un PDF à partir de HTML. Si output est fourni, les pages générées y sont ajoutées et l’objet est renvoyé ; sinon la fonction renvoie le flux d’octets (byte) du PDF.

Exemple : générer et renvoyer un PDF en réponse à une requête web.

python
import frappe
from frappe.utils.pdf import get_pdf

@frappe.whitelist(allow_guest=True)
def generate_invoice():
    cart = [{
        'Samsung Galaxy S20': 10,
        'iPhone 13': 80
    }]

    html = '<h1>Invoice from Star Electronics e-Store!</h1>'

    # Add items to PDF HTML
    html += '<ol>'
    for item, qty in cart.items():
        html += f'<li>{item} - {qty}</li>'
    html += '</ol>'

    # Attaching PDF to response
    frappe.local.response.filename = 'invoice.pdf'
    frappe.local.response.filecontent = get_pdf(html)
    frappe.local.response.type = 'pdf'

Cache et e-mail

frappe.cache()

cache()

Renvoie la connexion Redis, instance de la classe RedisWrapper qui hérite de redis.Redis. Vous pouvez l’utiliser pour stocker et lire des paires clé-valeur dans le cache Redis.

python
import frappe

cache = frappe.cache()

cache.set('name', 'frappe') # True
cache.get('name') # b'frappe'

frappe.sendmail()

sendmail(recipients=[], sender="", subject="No Subject", message="No Message", as_markdown=False, template=None, args=None, **kwargs)

ParamètreRôle
recipientsListe des destinataires.
senderExpéditeur. Par défaut, l’utilisateur courant ou le compte sortant par défaut.
subjectObjet de l’e-mail.
message(ou content) Contenu de l’e-mail.
as_markdownConvertit le contenu Markdown en HTML.
templateNom d’un template HTML (Jinja) du dossier templates/emails.
argsArguments pour le rendu du template.

Dans la plupart des cas, ces arguments suffisent, mais la fonction accepte beaucoup d’autres arguments nommés. Pour les connaître tous, consultez son implémentation dans frappe/__init__.py.

Cette fonction envoie un e-mail via le compte e-mail (Email Account) par défaut de l’utilisateur ou le compte e-mail par défaut global.

python
import frappe

recipients = [
    '[email protected]',
    '[email protected]'
]

frappe.sendmail(
    recipients=recipients,
    subject=frappe._('Birthday Reminder'),
    template='birthday_reminder',
    args=dict(
        reminder_text=reminder_text,
        birthday_persons=birthday_persons,
        message=message,
    ),
    header=_('Birthday Reminder 🎂')
)

Exemple de fichier de template Jinja :

html
<!-- templates/emails/birthday_reminder.html -->
<div>
<div class="gray-container text-center">
<div>
 {% for person in birthday_persons %}
 {% if person.image %}
 <img src="{{ person.image }}" title="{{ person.name }}">
 {% endif %}
 {% endfor %}
 </div>
<div style="margin-top: 15px;">
<span>{{ reminder_text }}</span>
<p class="text-muted">{{ message }}</p>
</div>
</div>

Joindre des fichiers

Vous pouvez joindre des fichiers à l’e-mail en passant une liste de pièces jointes à sendmail :

python
frappe.sendmail(
    ["[email protected]", "[email protected]"],
    message="## hello, *bro*"
    attachments=[{"file_url": "/files/hello.png"}],
    as_markdown=True
)

Les pièces jointes sont une liste de dictionnaires avec une clé file_url. Cette valeur se trouve dans le champ file_url d’un document File.

Synchronisation et liens

filelock

Un verrou de fichier (file lock) permet de synchroniser des processus et d’éviter les situations de concurrence (race conditions).

Exemple : l’écriture dans un fichier peut provoquer une situation de concurrence si plusieurs processus écrivent en même temps. On crée donc un verrou nommé, visible par les processus, qui attendent qu’il soit libéré avant d’écrire.

python
from frappe.utils.synchronization import filelock

def update_important_config(config, file):
    with filelock("config_name"):
        json.dumps(config, file)

get_filtered_list_url

get_filtered_list_url(doctype, docnames=None)

Utile quand plusieurs documents viennent d’être créés et que vous voulez tous les montrer ensemble à l’utilisateur dans la vue liste.

python
from frappe.utils import get_filtered_list_url

get_filtered_list_url("Work Order", [
    "MFG-WO-2025-00027",
    "MFG-WO-2025-00028",
    "MFG-WO-2025-00029"
])
# → 'http://&lt;site&gt;/app/work-order?name=["in",["MFG-WO-2025-00027","MFG-WO-2025-00028","MFG-WO-2025-00029"]]'

get_filtered_list_link(doctype, docnames=None, label=None)

Utile quand plusieurs documents viennent d’être créés : au lieu d’afficher une longue liste de liens dans une boîte de message, vous affichez un seul lien propre.

python
from frappe.utils import get_filtered_list_link

get_filtered_list_link("Work Order", [
    "MFG-WO-2025-00027",
    "MFG-WO-2025-00028",
])
# → '<a href="http://&lt;site>/app/work-order?name=[...]">Work Order</a>'

Pages liées

Fonctions utilitaires Frappe : frappe.utils en Python | ERPNext Lab