.Net REST client for Frappe Framework
using Frappe.Net
var frappe = new Frappe("https://base-url.com/");
To ping a Frappe Site use the PingAsync
method.
...
var res = await frappe.PingAsync()
Console.WriteLine(res) // pong
When the debug mode is on, Frappe.Net logs all HTTP requests in debug console
var frappe = new Frappe("https://base-url.com/", true);
Frappe.Net supports all Frappe Framework REST authentication methods. It attempts to validate credentials once supplied, as such all athentication functions are asynchronous. All authentication methods support fluent style coding.
frappe.UseTokenAync("api-key", "api-secret");
Logging in with password yields cookie data of type IDictionary<string, string>
that contains the keys sid
, system_user
, full_name
, user_id
and user_image
. Session data is maintained, so there is no need to supply username and password again for subsequent requests.
var cookies = await frappe.UsePasswordAync("email-or-username", "password");
Console.WriteLine(cookies[Cookies.FieldNames.UserId]); // Administrator
frappe.UseAccessTokenAync("oauth-access-token");
var user = await frappe.UseTokenAync("api-key", "api-secret")
.GetLoggedUserAsync()
Console.WriteLine(user); // administrator
The methods implemented corellates to RESTful requests that are mapped to the /api/resource
in Frappe. Also, some other frappe.client
APImethods are implemented here.
To get a list of records of a DocType use Frappe.Db.GetListAsync()
var frappe = new Frappe(baseUrl);
await frappe.UseTokenAsync(apiKey, apiSecret);
string[] fields = {
"name",
"description",
"status"
};
string[,] filters = {
{
"status", "=", "Open"
}
};
var todos = await frappe.Db.GetListAsync(
"ToDo",
fields:fields,
filters:filters,
orderBy: "modified desc",
limitStart: 10,
limitPageLenght: 30,
);
foreach ( var t in todos) {
console.WriteLine($"{t.name} -> {t.description} : {t.status}");
}
By default Frappe will return 20 records and will only fetch the name of the records unless fields supplied.
string[,] filters = {
{
"status", "=", "Closed"
}
};
int count = frappe.Db.GetCount("ToDo"); // count all close ToDo
To get a document with a document name use the GetAsync
method.
...
var doc = await frappe.Db.GetAsync("ToDo", "340a5acab3");
Console.WriteLine(doc.name); // 340a5acab3
This method will throw a KeyNotFoundException
if the document for the suplied name is not found.
...
string[,] filter = { { "name", "=", "bafc4c81fe" } };
var value = await frappe.Db.GetValueAsync("ToDo", "description", filter);
Console.WriteLine(value) // Some ToDo description
...
var value = await frappe.Db.GetSingleValueAsync("Website Settings", "website_theme");
Console.WriteLine(doc.name) // Standard
...
// returns the updated document as a ```dynamic``` object
await frappe.Db.SetValueAsync("ToDo", doc.name.ToObject<string>(), "description", data);
...
var doc = await frappe.Db.InsertAsync(
new Dictionary<string, object> {
{ "doctype", "ToDo"},
{ "description", desc}
}
);
Console.WriteLine(doc.description.ToString()); // desc
...
Dictionary<string, object>[] manyDocs = {
new Dictionary<string, object> {
{ "doctype", "ToDo"},
{ "description","Description 1"}
},
new Dictionary<string, object> {
{ "doctype", "ToDo"},
{ "description", "Description 2"}
}
};
var docs = await frappe.Db.InsertManyAsync(manyDocs);
Console.WriteLine((int)docs.Count); // 2
var doc = await Frappe.Db.GetAsync("ToDo", "xxxxxx");
doc.description = "new description";
// Note that the document received from Get will not contain a
// ```doctype``` property for hence the need to add it before save
doc.doctype = "ToDo";
await Frappe.Db.SaveAsync(doc);
var updateDoc = await Frappe.Db.GetAsync("ToDo", doc.name.ToString());