Summary of all ways to extend server side logics in Frappe Framework

Dear community,

I this thread I would like to summarize ways to extend server side logics in Frappe (python). This is based on my experiences thus far.

Till now, I only find 4 ways.

  1. Use doc_event hooks
  2. Class method extension
  3. Whitelisted method override
  4. Monkey patching

Note: #1 option is most recommended, #4 is least recommended.

1) Use doc_events hooks

This is the most used and recommended as it is easier to maintain than other methods.

https://frappeframework.com/docs/user/en/python-api/hooks#crud-events

Pros

  • Works without overriding the original logic, it is an incremental work.
  • Easy to use, recommended to use before other methods.

Cons

  • Not as flexible as it should be,i.e., we can’t control the order of execution, nor prevent existing code from happening.
  • Limited hook point such as validate, after_insert, on_update, etc…

2) Class method extension

This method is used to extend Class’s method only. It is flexible, the second best method.

https://frappeframework.com/docs/user/en/python-api/hooks#override-doctype-class

Pros

  • Calling super() allows for better control over the order of code execution.
  • Can be used with any method, not just CRUD like doc_events.
  • This is the standard Python method.

Cons

  • If there are 2 Downstream apps extending the same class, the latter will override the first.
  • Can only be used with Class methods, can’t be used with floating functions

Note: If it’s a floating function, you have to use override type 3 or 4

3) Whitelisted method override

https://frappeframework.com/docs/user/en/python-api/hooks#override-whitelisted-methods

Pros

  • Easy to use, it will directly override the whitelisted method

Cons

  • It is an override, not an extension which I don’t really like it much.
  • Can only be used with floating whitelisted methods (not Class’s whitelist methods)
  • Can’t be used with non-whitelisted methods (which will need last resource, the monkey patch)

4) Monkey patch

This method must be said to be not the Framework’s approach, but in many cases it cannot be avoided (floating and non-whitelisted methods)

Pros

  • It is the last ways

Disadvantages

  • It is an override, not an extension
  • Writing a patch in __ init __.py will work even if the app with this patch is not installed (if not installed, you have to delete it from the apps folder).

So, how you find this useful, and please correct me if there are better ways out there. :slight_smile:

7 Likes

This is an excellent post; thank you for sharing!

I believe there is a 5) Server Script, which has similar capabilities to editing hooks.

Pros

  • You make changes via a web browser, instead of hooks.py. This makes it a bit more accessible.

Disadvantages

  • Your changes aren’t as visible/obvious. Another person who examines `hooks.py’ won’t see anything. They must remember to also go look in the Server Scripts. Comparing and contrasting what’s in there.

And I guess 6) would be Forking. I’ve had to do that sometimes, because what I needed to accomplish was too awkward or risky with Monkey Patching. Or because I just wanted an easy way to perform a diff between my code, versus official code.

3 Likes

As soon as the official support for a version is stopped, it becomes easily forkable.

That means whoever is using less than v14 today can fork without any worry of diverging the code.

1 Like