[docs] for frappe client #2209
This commit is contained in:
parent
a16e6a143f
commit
638816acd0
3 changed files with 140 additions and 4 deletions
|
|
@ -8,14 +8,33 @@ import frappe.model
|
|||
import frappe.utils
|
||||
import json, os
|
||||
|
||||
'''
|
||||
Handle RESTful requests that are mapped to the `/api/resource` route.
|
||||
|
||||
Requests via FrappeClient are also handled here.
|
||||
'''
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_list(doctype, fields=None, filters=None, order_by=None,
|
||||
limit_start=None, limit_page_length=20):
|
||||
'''Returns a list of records by filters, fields, ordering and limit
|
||||
|
||||
:param doctype: DocType of the data to be queried
|
||||
:param fields: fields to be returned. Default is `name`
|
||||
:param filters: filter list by this dict
|
||||
:param order_by: Order by this fieldname
|
||||
:param limit_start: Start at this index
|
||||
:param limit_page_length: Number of records to be returned (default 20)'''
|
||||
return frappe.get_list(doctype, fields=fields, filters=filters, order_by=order_by,
|
||||
limit_start=limit_start, limit_page_length=limit_page_length, ignore_permissions=False)
|
||||
|
||||
@frappe.whitelist()
|
||||
def get(doctype, name=None, filters=None):
|
||||
'''Returns a document by name or filters
|
||||
|
||||
:param doctype: DocType of the document to be returned
|
||||
:param name: return document of this `name`
|
||||
:param filters: If name is not set, filter by these values and return the first match'''
|
||||
if filters and not name:
|
||||
name = frappe.db.get_value(doctype, json.loads(filters))
|
||||
if not name:
|
||||
|
|
@ -29,6 +48,12 @@ def get(doctype, name=None, filters=None):
|
|||
|
||||
@frappe.whitelist()
|
||||
def get_value(doctype, fieldname, filters=None, as_dict=True, debug=False):
|
||||
'''Returns a value form a document
|
||||
|
||||
:param doctype: DocType to be queried
|
||||
:param fieldname: Field to be returned (default `name`)
|
||||
:param filters: dict or string for identifying the record'''
|
||||
|
||||
if not frappe.has_permission(doctype):
|
||||
frappe.throw(_("Not permitted"), frappe.PermissionError)
|
||||
|
||||
|
|
@ -80,6 +105,9 @@ def set_value(doctype, name, fieldname, value=None):
|
|||
|
||||
@frappe.whitelist()
|
||||
def insert(doc=None):
|
||||
'''Insert a document
|
||||
|
||||
:param doc: JSON or dict object to be inserted'''
|
||||
if isinstance(doc, basestring):
|
||||
doc = json.loads(doc)
|
||||
|
||||
|
|
@ -95,6 +123,9 @@ def insert(doc=None):
|
|||
|
||||
@frappe.whitelist()
|
||||
def insert_many(docs=None):
|
||||
'''Insert multiple documents
|
||||
|
||||
:param docs: JSON or list of dict objects to be inserted in one request'''
|
||||
if isinstance(docs, basestring):
|
||||
docs = json.loads(docs)
|
||||
|
||||
|
|
@ -118,6 +149,9 @@ def insert_many(docs=None):
|
|||
|
||||
@frappe.whitelist()
|
||||
def save(doc):
|
||||
'''Update (save) an existing document
|
||||
|
||||
:param doc: JSON or dict object with the properties of the document to be updated'''
|
||||
if isinstance(doc, basestring):
|
||||
doc = json.loads(doc)
|
||||
|
||||
|
|
@ -126,11 +160,19 @@ def save(doc):
|
|||
|
||||
@frappe.whitelist()
|
||||
def rename_doc(doctype, old_name, new_name, merge=False):
|
||||
'''Rename document
|
||||
|
||||
:param doctype: DocType of the document to be renamed
|
||||
:param old_name: Current `name` of the document to be renamed
|
||||
:param new_name: New `name` to be set'''
|
||||
new_name = frappe.rename_doc(doctype, old_name, new_name, merge=merge)
|
||||
return new_name
|
||||
|
||||
@frappe.whitelist()
|
||||
def submit(doc):
|
||||
'''Submit a document
|
||||
|
||||
:param doc: JSON or dict object to be submitted remotely'''
|
||||
if isinstance(doc, basestring):
|
||||
doc = json.loads(doc)
|
||||
|
||||
|
|
@ -141,6 +183,10 @@ def submit(doc):
|
|||
|
||||
@frappe.whitelist()
|
||||
def cancel(doctype, name):
|
||||
'''Cancel a document
|
||||
|
||||
:param doctype: DocType of the document to be cancelled
|
||||
:param name: name of the document to be cancelled'''
|
||||
wrapper = frappe.get_doc(doctype, name)
|
||||
wrapper.cancel()
|
||||
|
||||
|
|
@ -148,6 +194,10 @@ def cancel(doctype, name):
|
|||
|
||||
@frappe.whitelist()
|
||||
def delete(doctype, name):
|
||||
'''Delete a remote document
|
||||
|
||||
:param doctype: DocType of the document to be deleted
|
||||
:param name: name of the document to be deleted'''
|
||||
frappe.delete_doc(doctype, name)
|
||||
|
||||
@frappe.whitelist()
|
||||
|
|
@ -158,6 +208,9 @@ def set_default(key, value, parent=None):
|
|||
|
||||
@frappe.whitelist()
|
||||
def make_width_property_setter(doc):
|
||||
'''Set width Property Setter
|
||||
|
||||
:param doc: Property Setter document with `width` property'''
|
||||
if isinstance(doc, basestring):
|
||||
doc = json.loads(doc)
|
||||
if doc["doctype"]=="Property Setter" and doc["property"]=="width":
|
||||
|
|
@ -165,6 +218,9 @@ def make_width_property_setter(doc):
|
|||
|
||||
@frappe.whitelist()
|
||||
def bulk_update(docs):
|
||||
'''Bulk update documents
|
||||
|
||||
:param docs: JSON list of documents to be updated remotely. Each document must have `docname` property'''
|
||||
docs = json.loads(docs)
|
||||
failed_docs = []
|
||||
for doc in docs:
|
||||
|
|
@ -184,17 +240,32 @@ def bulk_update(docs):
|
|||
|
||||
@frappe.whitelist()
|
||||
def has_permission(doctype, docname, perm_type="read"):
|
||||
'''Returns a JSON with data whether the document has the requested permission
|
||||
|
||||
:param doctype: DocType of the document to be checked
|
||||
:param docname: `name` of the document to be checked
|
||||
:param perm_type: one of `read`, `write`, `create`, `submit`, `cancel`, `report`. Default is `read`'''
|
||||
# perm_type can be one of read, write, create, submit, cancel, report
|
||||
return {"has_permission": frappe.has_permission(doctype, perm_type.lower(), docname)}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_password(doctype, name, fieldname):
|
||||
'''Return a password type property. Only applicable for System Managers
|
||||
|
||||
:param doctype: DocType of the document that holds the password
|
||||
:param name: `name` of the document that holds the password
|
||||
:param fieldname: `fieldname` of the password property
|
||||
'''
|
||||
frappe.only_for("System Manager")
|
||||
return frappe.get_doc(doctype, name).get_password(fieldname)
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_js(items):
|
||||
'''Load JS code files. Will also append translations
|
||||
and extend `frappe._messages`
|
||||
|
||||
:param items: JSON list of paths of the js files to be loaded.'''
|
||||
items = json.loads(items)
|
||||
out = []
|
||||
for src in items:
|
||||
|
|
|
|||
|
|
@ -2,6 +2,13 @@ import requests
|
|||
import json
|
||||
import frappe
|
||||
|
||||
'''
|
||||
FrappeClient is a library that helps you connect with other frappe systems
|
||||
|
||||
|
||||
|
||||
'''
|
||||
|
||||
class AuthError(Exception):
|
||||
pass
|
||||
|
||||
|
|
@ -13,7 +20,7 @@ class FrappeClient(object):
|
|||
self.verify = verify
|
||||
self.session = requests.session()
|
||||
self.url = url
|
||||
self.login(username, password)
|
||||
self._login(username, password)
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
|
@ -21,7 +28,8 @@ class FrappeClient(object):
|
|||
def __exit__(self, *args, **kwargs):
|
||||
self.logout()
|
||||
|
||||
def login(self, username, password):
|
||||
def _login(self, username, password):
|
||||
'''Login/start a sesion. Called internally on init'''
|
||||
r = self.session.post(self.url, data={
|
||||
'cmd': 'login',
|
||||
'usr': username,
|
||||
|
|
@ -34,6 +42,7 @@ class FrappeClient(object):
|
|||
raise AuthError
|
||||
|
||||
def logout(self):
|
||||
'''Logout session'''
|
||||
self.session.get(self.url, params={
|
||||
'cmd': 'logout',
|
||||
}, verify=self.verify)
|
||||
|
|
@ -54,41 +63,65 @@ class FrappeClient(object):
|
|||
return self.post_process(res)
|
||||
|
||||
def insert(self, doc):
|
||||
'''Insert a document to the remote server
|
||||
|
||||
:param doc: A dict or Document object to be inserted remotely'''
|
||||
res = self.session.post(self.url + "/api/resource/" + doc.get("doctype"),
|
||||
data={"data":frappe.as_json(doc)}, verify=self.verify)
|
||||
return self.post_process(res)
|
||||
|
||||
def insert_many(self, docs):
|
||||
'''Insert multiple documents to the remote server
|
||||
|
||||
:param docs: List of dict or Document objects to be inserted in one request'''
|
||||
return self.post_request({
|
||||
"cmd": "frappe.client.insert_many",
|
||||
"docs": frappe.as_json(docs)
|
||||
})
|
||||
|
||||
def update(self, doc):
|
||||
'''Update a remote document
|
||||
|
||||
:param doc: dict or Document object to be updated remotely. `name` is mandatory for this'''
|
||||
url = self.url + "/api/resource/" + doc.get("doctype") + "/" + doc.get("name")
|
||||
res = self.session.put(url, data={"data":frappe.as_json(doc)}, verify=self.verify)
|
||||
return self.post_process(res)
|
||||
|
||||
def bulk_update(self, docs):
|
||||
'''Bulk update documents remotely
|
||||
|
||||
:param docs: List of dict or Document objects to be updated remotely (by `name`)'''
|
||||
return self.post_request({
|
||||
"cmd": "frappe.client.bulk_update",
|
||||
"docs": frappe.as_json(docs)
|
||||
})
|
||||
|
||||
def delete(self, doctype, name):
|
||||
'''Delete remote document by name
|
||||
|
||||
:param doctype: `doctype` to be deleted
|
||||
:param name: `name` of document to be deleted'''
|
||||
return self.post_request({
|
||||
"cmd": "frappe.model.delete_doc",
|
||||
"doctype": doctype,
|
||||
"name": name
|
||||
})
|
||||
|
||||
def submit(self, doclist):
|
||||
def submit(self, doc):
|
||||
'''Submit remote document
|
||||
|
||||
:param doc: dict or Document object to be submitted remotely'''
|
||||
return self.post_request({
|
||||
"cmd": "frappe.client.submit",
|
||||
"doclist": frappe.as_json(doclist)
|
||||
"doc": frappe.as_json(doc)
|
||||
})
|
||||
|
||||
def get_value(self, doctype, fieldname=None, filters=None):
|
||||
'''Returns a value form a document
|
||||
|
||||
:param doctype: DocType to be queried
|
||||
:param fieldname: Field to be returned (default `name`)
|
||||
:param filters: dict or string for identifying the record'''
|
||||
return self.get_request({
|
||||
"cmd": "frappe.client.get_value",
|
||||
"doctype": doctype,
|
||||
|
|
@ -97,6 +130,12 @@ class FrappeClient(object):
|
|||
})
|
||||
|
||||
def set_value(self, doctype, docname, fieldname, value):
|
||||
'''Set a value in a remote document
|
||||
|
||||
:param doctype: DocType of the document to be updated
|
||||
:param docname: name of the document to be updated
|
||||
:param fieldname: fieldname of the document to be updated
|
||||
:param value: value to be updated'''
|
||||
return self.post_request({
|
||||
"cmd": "frappe.client.set_value",
|
||||
"doctype": doctype,
|
||||
|
|
@ -106,6 +145,10 @@ class FrappeClient(object):
|
|||
})
|
||||
|
||||
def cancel(self, doctype, name):
|
||||
'''Cancel a remote document
|
||||
|
||||
:param doctype: DocType of the document to be cancelled
|
||||
:param name: name of the document to be cancelled'''
|
||||
return self.post_request({
|
||||
"cmd": "frappe.client.cancel",
|
||||
"doctype": doctype,
|
||||
|
|
@ -113,6 +156,12 @@ class FrappeClient(object):
|
|||
})
|
||||
|
||||
def get_doc(self, doctype, name="", filters=None, fields=None):
|
||||
'''Returns a single remote document
|
||||
|
||||
:param doctype: DocType of the document to be returned
|
||||
:param name: (optional) `name` of the document to be returned
|
||||
:param filters: (optional) Filter by this dict if name is not set
|
||||
:param fields: (optional) Fields to be returned, will return everythign if not set'''
|
||||
params = {}
|
||||
if filters:
|
||||
params["filters"] = json.dumps(filters)
|
||||
|
|
@ -125,6 +174,11 @@ class FrappeClient(object):
|
|||
return self.post_process(res)
|
||||
|
||||
def rename_doc(self, doctype, old_name, new_name):
|
||||
'''Rename remote document
|
||||
|
||||
:param doctype: DocType of the document to be renamed
|
||||
:param old_name: Current `name` of the document to be renamed
|
||||
:param new_name: New `name` to be set'''
|
||||
params = {
|
||||
"cmd": "frappe.client.rename_doc",
|
||||
"doctype": doctype,
|
||||
|
|
|
|||
|
|
@ -137,10 +137,21 @@ def parse(docs):
|
|||
def strip_leading_tabs(docs):
|
||||
"""Strip leading tabs from __doc__ text."""
|
||||
lines = docs.splitlines()
|
||||
|
||||
# remove empty lines in the front
|
||||
start = 0
|
||||
for line in lines:
|
||||
if line != '': break
|
||||
start += 1
|
||||
if start:
|
||||
lines = lines[start:]
|
||||
|
||||
# remove default indentation
|
||||
if len(lines) > 1:
|
||||
start_line = 1
|
||||
ref_line = lines[start_line]
|
||||
while not ref_line:
|
||||
# find reference line for indentations (the first line that is nonempty (false))
|
||||
start_line += 1
|
||||
if start_line > len(lines): break
|
||||
ref_line = lines[start_line]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue