# Scripts python

**Un script python vous permet d'écrire un script exécuté sur le server et généré via un événement de document ou via l'API**

## 1. Comment créer un script python

Pour créer un script python :

1. Vous devez ajouter la clé `server_script_enabled` et la définir comme étant vraie (ou 1) dans le fichier site_config.json de votre site.
1. Pour ajouter / modifier un script python, assurez-vous d'avoir le rôle **Gestionnaire de script**
1. Créez un nouveau script python via "Nouveau script python" dans la barre d'outils.
1. Choisissez le type de script python (Evénement de document / API).
1. Choisissez le type de document de référence et le nom de l'événement, ou le nom de la méthode, ajoutez votre script et enregistrez.

## 2. Fonctionnalités

### 2.1 Autoriser les scripts python

Les scripts python doivent être activés via le fichier site_config.json

```
bench --site {votre_site} set-config server_script_enabled true
```

### 2.2 Evénements de document

Pour les scripts qui sont lancés via des événements de documents, vous devez définir le type de document de référence et le nom de l'événement générateur :

- Avant l'insertion
- Avant l'enregistrement
- Après l'enregistrement
- Avant la validation
- Après la validation
- Avant l'annulation
- Après l'annulation
- Avant la suppression
- Après la suppression

### 2.3 Scripts API

Vous pouvez créer une nouvelle API qui sera accessible via `api/method/[methodname]` en sélectionnant le type de script "API".

Si vous voulez qu'un utilisateur invité (non connecté) accède à l'API, cochez la case "Autoriser les invités".

La réponse sera envoyée dans un objet de type `frappe.response["message"]`.

### 2.3 Securité

dokos utilise la librairie RestrictedPython pour restreindre l'accès aux méthodes disponibles pour les scripts python. Seules les méthodes sûres, listées ci-dessous sont disponibles dans les scripts serveur.
```py
json # module json
dict # dict interne
frappe._ # méthod de traduction
frappe._dict # méthode interne frappe._dict
frappe.flags # flags globaux

# FORMATTING
frappe.format # frappe.format_value(value, dict(fieldtype='Currency'))
frappe.format_value # frappe.format_value(value, dict(fieldtype='Currency'))
frappe.date_format # format de date par défaut
frappe.format_date # retourne une date sous la forme "1er septembre 2019"

# SESSION
frappe.form_dict # paramètres de requêtes / formulaires
frappe.request # objet de requête
frappe.response # objet de réponse
frappe.session.user # utilisateur actuel
frappe.session.csrf_token # jeton CSRF de la session en cours
frappe.user  # utilisateur actuel
frappe.get_fullname # nom complet de l'utilisateur actuel
frappe.get_gravatar # frappe.utils.get_gravatar_url
frappe.full_name = # nom complet de l'utilisateur actuel

# ORM
frappe.get_meta # obtenir l'objet de métadonnées
frappe.get_doc
frappe.get_cached_doc
frappe.get_list
frappe.get_all
frappe.get_system_settings

# DB
frappe.db.get_list
frappe.db.get_all
frappe.db.get_value
frappe.db.get_single_value
frappe.db.get_default
frappe.db.escape

# UTILITIES
frappe.msgprint # msgprint
frappe.get_hooks # hooks de l'application
frappe.utils # méthodes de frappe.utils
frappe.render_template # frappe.render_template,
frappe.get_url # frappe.utils.get_url
socketio_port # port for socketio
style.border_color # '#d1d8dd'
guess_mimetype = mimetypes.guess_type,
html2text = html2text,
dev_server # Vrai si en mode développeur
```

## 3. Exemples

### 3.1 Changer la valeur d'une propriété avant enregistrement

Type de script: **Avant l'enregistrement**

```py
if "test" in doc.description:
	doc.status = 'Closed'
```

### 3.2 Validation personnalisée

Type de script:: **Avant l'enregistrement**

```py
if "validate" in doc.description:
	raise frappe.ValidationError
```

### 3.3. Auto création d'un ToDo

Type de script:: **Après l'enregistrement**

```py
if doc.allocted_to:
    frappe.get_doc(dict(
        doctype = 'ToDo'
        owner = doc.allocated_to,
        description = doc.subject
    )).insert()
```

### 3.4 API

- Type de script:: **API**
- Nom de la méthode: `test_method`

```py
frappe.response['message'] = "hello"
```

Requête: `/api/method/test_method`