Frappe Licensing & Software Architecture

Google banned AGPL for this reason: AGPL Policy  |  Google Open Source

The primary risk presented by AGPL is that any product or service that depends on AGPL-licensed code, or includes anything copied or derived from AGPL-licensed code, may be subject to the virality of the AGPL license. This viral effect requires that the complete corresponding source code of the product or service be released to the world under the AGPL license. This is triggered if the product or service can be accessed over a remote network interface, so it does not even require that the product or service is actually distributed. Because Google’s core products are services that users interact with over a remote network interface (Search, Gmail, Maps, YouTube), the consequences of an engineer accidentally depending on AGPL for one of these services are so great that we maintain an aggressively-broad ban on all AGPL software to doubly-ensure that AGPL could never be incorporated in these services in any manner.

1 Like

“Incorporating” and “depending on to do significant work” aren’t the same thing, though.

The question here is not code that is “copied from or derived from AGPL-licenced code.” Copying-and-pasting code would clearly be in violation of the license. The question, rather, is apps run adjacent to AGPL apps with no shared code but possibly consuming their data or sending data to them.

As you quoted earlier:

However, in many cases you can distribute the GPL-covered software alongside your proprietary system. To do this validly, you must make sure that the free and nonfree programs communicate at arms length, that they are not combined in a way that would make them effectively a single program.

In this regard, the Frappe framework acts as a mediator between AGPL and non-AGPL apps. Are you saying that Frappe does not consider this mediation “arms length”? I’m surprised by that implication, so it would be great to get some clarity.

1 Like

@peterg

Lets use an example of using AGPLed code like Builder:

When you do frappe.get_doc("Builder Page", ...) aren’t you effectively using builder as a library? You’re not just exchanging data here, you get access to class defined inside builder, you can execute builder code with it and so on.

In this case that get_doc is effectively same as:

from builder.doctype.builder_page import BuilderPage
page = BuilderPage(...)
2 Likes

If this is Frappe’s stance, I hope you’ll make it publicly explicit. I don’t think I’ve ever seen this stated anywhere before. I don’t agree with your interpretation, but it is significant if this is Frappe’s official position. Even as GPL, there are huge implications for ERPNext here as well.

1 Like

If this is Frappe’s stance, I hope you’ll make it publicly explicit.

I’ll talk to others and draft a document. In any case, we are not litigious about licenses so far :smile:

I deliberately used “In spirit of license”.

If you need your product/service to be proprietary while depending on AGPL code, you SHOULD get it checked by lawyers.

5 Likes

Someone else can still sue you for license violation, our interpretation doesn’t matter.

E.g. Software Freedom Conservancy sues Vizio for GPL violations | ZDNET

1 Like

In principle we are very much for the idea of free software and that the primary goal of free software is freedom and not making a business. Our new licenses reflect that.

Though we have not explictly mentioned, applications that are used by end customers are AGPL and pure developer tools (like Frappe UI) are MIT.

Maybe like how @ankush said, we will make a policy around this, but hope this is clear in principle.

5 Likes

Frappe’s commitment to open source is clear and beautiful. I’ve really admired the organizations ethos, long after I came to enjoy the framework.

I think where things get less clear is what counts as “incorporating” AGPL/GPL software.

In Ankush’s example, I appreciate that a get_doc call and an import statement are functionally very similar. Functionality aside, though , I’d still argue that they’re different in important ways. It’s been explained to me that way by people much smarter than I am, at least. A public API is by definition public, a way for two bits of code to talk to each other without being the same program. Even if whole class objects get exposed, a public/private interface is still being crossed.

If Frappe’s stance is that class access is the threshold here, I’d wonder about Rushabh’s earlier statement about Builder pages. If they make API calls that return class instances, wouldn’t they also have to be licensed AGPL? If I write a server script that interacts with HRMS data, do I have to make it conspicuously available to anyone who uses my site? To push it even further, what happens when the Frappe app calls Helpdesk doctype methods?

I don’t make a dime selling software or development services. I’m just an enthusiastic end user. I do think there are some high-stakes ambiguities here, though, that only Frappe is in a position to clarify. A statement about how Frappe understands the AGPL to affect sibling apps would go a long way, I think.

3 Likes

This is an interesting question, specially for Builder because Builder is both the design and publishing tool. Builder pages though I reckon are not derivative of Builder (just like documents written in say Libre Office are not derivatives of Libre Office) and should not be subject to the AGPL.

Maybe we can license Builder under a more permissible license, or separate the Builder into a build and publish tool, or maybe just port the builder publishing part in the Framework itself so the publishing API is not subject to AGPL. Thoughts @surajshetty @ankush

2 Likes

@ankush

When you do frappe.get_doc("Builder Page", ...) aren’t you effectively using builder as a library? You’re not just exchanging data here, you get access to class defined inside builder, you can execute builder code with it and so on.

What if you do the same thing over the REST API that Frappe Framework provides for every Doctype? The standard interpretation of any GPL license (including AGPL) is that this is allowed usage, and does not trigger the viral clause in the license.

There is little functional difference between calling frappe.get_doc() and using the REST API, except it is a bad practice to go through the REST API if both apps are running in the same process.

This is exactly my 3rd question in the opening post: what is considered the public API of a Frappe app? Is it only the REST API, or is there also an in-process API provided by the Frappe Framework?

My instinct would say that the public APIs are:

  • APIs available out of process (autogenerated REST API, controller methods whitelisted for network usage … etc.)
  • Doctype definitions (these are required to use the above APIs as well and to make sense of the data provided by the app)
  • Any in-process APIs that allow the user to access the functionality of the app but not alter it in any way.

For Example, it should be fine to use frappe.get_doc() or the Query Builder to get access to the data stored by the app, or execute the logic defined in the app using API entry points.

However, in my opinion, it should be regarded as derived work (and trigger the xGPL viral clause) if:

  • custom fields or other customizations are added to an app
  • the computation logic of the app is modified through some framework means (e.g. hooks, client and server scripts)
  • application code is directly used by the other app (e.g. using import)

So in my opinion there are many parts here that require clarification and clear rules.

Software Freedom Conservancy usually represents specific developers whose GPL licensed code was incorporated into the Linux kernel, U-Boot, Busybox … etc. It is not like they are going around and randomly suing companies failing to release GPLed code.

So while it is true that any Frappe user could sue over a GPL violation, they would have a much weaker case, if the service provider/software vendor adhered to the clear licensing guidelines and license interpretation of the original developers of the used app(s).

1 Like

This is the standard interpretation: when someone publishes a page with Builder it is pretty similar to using a GPLed C/C++ compiler to build a proprietary software: it is acting as a data processing tool.

I don’t think that is necessary for the whole app. However, if the Builder includes AGPL javascript code libraries in the published pages, that could cause issues (I have not checked if this is the case).

It is standard practice with compilers that the runtime libraries that are used in the compiled programs are released under a less strict license (e.g. LGPL), while the rest of the compiler is covered by a strict copyleft license (e.g. GPL / AGPL).

1 Like

I’ve done a bit more digging on this and talked to our lawyer. A few notes for those interested:

First, I agree fully with Frappe Inc.'s decision to put new apps on the AGPL. The GPL just didn’t anticipate the rise of SaaS, and AGPL fixes that. This is the right license.

But, there is a question that requires clarification: on Frappe instances that use AGPL apps (Helpdesk, Builder, CRM, etc.), what are the licensing requirements of other apps on the same instance?

In broadstrokes the AGPL is clear.

  • If a program uses AGPL code as a library, that program must also be AGPL.
  • If a program interfaces with an AGPL program via an API, that program is not obligated to be AGPL.

The specifics, however, get messy. Here, the specific question is: Are Frappe apps programs or libraries?

In this thread, I believe Rushabh and Ankush are saying that Frappe Inc. regards apps to be libraries. I don’t agree with that interpretation, but also don’t have the legal or technical skills to argue the point with confidence. If true, however, the consequences are very significant.

If Frappe method calls like frappe.get_doc are understood to spread AGPL, all code on the same instance would also need to be openly published under the AGPL. This would likely include any in-house custom apps (even if they don’t interact with AGPL code directly) and all server scripts.

This has huge implications that go far beyond proprietary “for profit” apps. It means that if you use an AGPL frappe app on your instance, every single person who has access to that system has a legal entitlement to all other code on that instance. Offering the code on demand isn’t enough, either. According to section 13 of the AGPL, all code must be “prominently offer[ed]”.

My lawyer has advised me that, if we want to use AGPL apps and don’t want to dispute Frappe Inc’s interpretations, we would need to:

  1. share all of our apps and server scripts on a public repo,
  2. make sure that they stay up-to-date, and
  3. prominently advertise them on our site.

He adds, this obligation applies even for private, in-house stuff that we have no intention of selling or distributing.

Is this the intended effect of the move to AGPL on new apps? If so, I hope people are aware. If not, some clarifications might be needed.

2 Likes

Thank you @peterg for confirming the issues I have been raising in the starting post of this topic.

I think the best way forward would be the introduction of a “Frappe Framework Exception” to the AGPL license (Similar to the ClassPath Exception in the Java World), which would clearly specify what kind of interactions between apps would classify as “interfacing over an API”, and which would classify as “using the code as a library”.

Until then, AGPL code should be executed in separate Frappe sites in separate Python interpreters from all other code, and only interfaced with through network APIs (e.g. the REST API).

1 Like

For what it’s worth, the more research I do, the more I disagree with Rushabh and Ankush’s interpretation here.

The name of the page defining the get_doc interface is “Document API”. Calls are made via a well-defined, non-AGPL pathway, and anything access this way is made available by app designers. It is possible to write code that is not accessible to the Frappe APIs.

But, this gets very technical, and for that reason author’s intent does matter. I hope we get some clarification. The compliance obligations for in-house apps/scripts are pretty enormous, and it’s hard to believe that’s the intention.

1 Like

Can you share the specific passages where we say this?

Any website / web-app built using Builder does not become AGPL if it only uses API calls, the same way any application that runs on Linux does not automatically become GPL (all apps running on Linux use Linux API)

The goal behind making these apps AGPL is that anyone who runs modified versions of Builder or CRM should give the same rights to the users, anyone who uses them as API backends does not have to make their applications AGPL.

Hope that is clear.

1 Like

@ankush wrote this a couple messages before:

@peterg and I disagree with this, because frappe.get_doc() is part of the public Document API provided by the Frappe Framework, it provides the same functionality as the REST API provided by the Frappe Framework. The only difference is that the Document API works only in the same Python process - but can easily access the Documents created by any App installed on the same site - this is one of the superpowers of Frappe Framework.

The second example is, in my opinion, using internal code, that would make the other app a derived product of the Builder app, and thus trigger the viral clause of the xGPL licenses.

Maybe we should look at a different example: the CRM App.

What if someone wants to create a custom, company specific, internal integration between ERPNext and the new CRM app. According to the recommended approach, they package this custom integration as a separate Frappe App. They have 2 options:

  • only use the REST APIs to communicate with the CRM app and ERPNext with no other interdependencies. In this case the App can even be installed on a separate site (possibly on a separate server).
  • install all 3 apps on the same site, but only use public Frappe Framework APIs (Document API, Query Builder API … etc.) to create the integration between CRM and ERPNext.

The first option does not trigger the AGPL viral clause for the internal app, because it is only using network APIs.

However, the second option triggers the AGPL viral clause, if we use the standard interpretation of application boundary == OS process boundary (in our case the Python interpreter).

If it would be clarified, that for a Frappe app, the application boundary is the Frappe App boundary (and public APIs) defined by the Frappe Framework, and multiple Apps can coexist in the same OS process (Python Interpreter), then the AGPL viral clause would not be triggered for the internal app.

The reason why I am advocating for an AGPL license extension that clarifies this (like the Java ClassPath GPL Exception that serves a very similar purpose), is because even if Frappe Inc. agrees to the above interpretation, any external contributor whose PR(s) were accepted into an AGPL app could sue anyone, who uses the app as I outlined here.

1 Like

Ankush and I have quite a bit of back and forth in this thread where that seems to be the message, at least as I understood it. The most explicit bit is probably the part @kisg quote right above me here.

I had asked if Frappe regarded API calls as sufficient “separation”:

Ankush’s responded by saying that get_doc is effectively the same as a library import. That distinction is extremely important in the context of the AGPL.

@ankush is an amazing software engineer who does huge amounts for the Frappe community, so I certainly value his opinion a great deal (even if I disagree with the specifics). Whatever Ankush’s personal view might be, though, the more important question right now is Frappe Inc.'s interpretation

When you joined the conversation, Rushabh, you didn’t get too far into the technical details, but you seemed (to me, at least) to be confirming Ankush’s interpretation, especially when talking about restructuring builder to use a different license. If framework api calls don’t spread the AGPL, I don’t think that would be necessary.

It seems things definitely aren’t yet clear! :slight_smile:

In any event, I’m glad to learn this might just be a miscommunication.

1 Like

Interesting conversation…

I’m not sure if an answer on this forum would actually suffice. As @kisg mentioned, it may be important to explicitly include this understanding in the license

Kind regards,

1 Like

Seems you are an expert in this. Can you help us draft one? We can include it in the license file.

The intent is that an direct derivatives of these apps should be AGPL, not those using the API without changing any core functionality.

4 Likes