Definition of Python API Surface In OmniGraph
#############################################

* Status: proposed
* Deciders: kpicott, OmniGraph devs
* Date: 2022-06-24

Technical Story: `OM-46154 <https://nvidia-omniverse.atlassian.net/browse/OM-46154>`_

Context and Problem Statement
=============================

Although the C++ ABI is stable and backwards compatible all of the Python code supplied by OmniGraph is, by the nature
of the language, public by default. This is causing problems with compatibility as much of the exposed code is
implementation detail that we wish to be able to change without affecting downstream customers. After a few iterations
we have run into many cases of unintentional dependencies, which will only grow more frequent as adoption grows.

Considered Options
==================

1. **The Wild West** - we leave everything exposed and let people use what they find useful. Behind the scenes we attempt
to maintain as much compatibility as we can, with deprecation notices where we cannot.
2. **Complete Lockdown** - we ship our Python modules as pre-interpreted bytecode (*.pyc* files), and tailor our
documentation to the specific code we wish to expose.
3. **PEP8 Play Nice** - we follow the `PEP8 Standard <https://peps.python.org/pep-0008/#public-and-internal-interfaces>`_
for defining public interfaces, where nothing is truly hidden but we do have a well-defined way of identifying the
interfaces we intend to support through multiple versions.

Decision Outcome
================

Option 3: it strikes a good balance of ease of development and ease of use.

Pros and Cons of the Options
============================

Option 1
--------

* **Good** - development is simpler as we don't have to worry about how to format or organize most Python code
* **Bad** - there is extra work involved in explicitly deprecating things that change, and since everything is visible
  the need for deprecation will be quite frequent.
* **Ugly** - if everything is fair game then users will start to make use of things that we either want to change or
  get rid of, making evolution of the interfaces much more difficult than they need to be

Option 2
--------

* **Good** - with everything well defined we make a strong statement as to what we are claiming to support.
* **Bad** - the code is still introspectable at the interface level even if the details are not. This makes it more
  likely that a mismatch in the code and the description will cause unreconcilable user confusion.
* **Ugly** - locking everything is inherently un-Pythonic and puts up artificial barriers to our primary goal in using
  Python, which is widespread adoption. The fact that the definitive documentation is outside of the code also
  contributes to those barriers.

Option 3
--------

* **Good** - we get a good balance of both worlds. The retained introspection makes it easier for seasoned
  programmers to understand how things are working and the API conventions make it clear where things are not meant to
  be relied on in future versions.
* **Bad** - there's a bit more work to follow the guidelines and not much automatic help in doing so. Internal
  developers have to be diligent in what they are exposing.
* **Ugly** - everything is still wide open and users are free to make use of anything in our system. Despite any
  warnings to the contrary `Hyrum's Law <https://abseil.io/resources/swe-book/html/ch01.html#hyrumapostrophes_law>`_
  dictates that it will be used anyway.
