Skip to content

yemikudaisi/FrappeRestClient.Net

Repository files navigation

FrappeRestClient.Net

NuGet Build status License: MIT

.Net REST client for Frappe Framework

Basic Usage

Create the Client

using Frappe.Net

var frappe = new Frappe("https://base-url.com/");

Test Connection to Frappe Site

To ping a Frappe Site use the PingAsync method.

...
var res = await frappe.PingAsync()
Console.WriteLine(res) // pong

Debug

When the debug mode is on, Frappe.Net logs all HTTP requests in debug console

var frappe = new Frappe("https://base-url.com/", true);

Authentication

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.

1. Token Based Authentication

frappe.UseTokenAync("api-key", "api-secret");

2. Password Based

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

3. Access Token

frappe.UseAccessTokenAync("oauth-access-token");

Get Logged In User

var user = await frappe.UseTokenAync("api-key", "api-secret")
	.GetLoggedUserAsync()

Console.WriteLine(user); // administrator

DB Funcitons

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.

Listing Documents

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.

Get Count

string[,] filters = { 
    { 
        "status", "=", "Closed" 
    } 
};
int count = frappe.Db.GetCount("ToDo"); // count all close ToDo

Get Single Document

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.

Get a Value from Document

...
string[,] filter = { { "name", "=", "bafc4c81fe" } };
var value = await frappe.Db.GetValueAsync("ToDo", "description", filter);
Console.WriteLine(value) // Some ToDo description

Get Single Value from Single-Type Document

...
var value = await frappe.Db.GetSingleValueAsync("Website Settings", "website_theme");
Console.WriteLine(doc.name) // Standard

Set a Single Value in a Document

...
// returns the updated document as a ```dynamic``` object
await frappe.Db.SetValueAsync("ToDo", doc.name.ToObject<string>(), "description", data);

Insert Document

...
var doc = await frappe.Db.InsertAsync(
    new Dictionary<string, object> {
        { "doctype", "ToDo"},
        { "description", desc}
    }
);
Console.WriteLine(doc.description.ToString()); // desc

Insert Many Document

...
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

Update (save) an existing Document

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());