> For the complete documentation index, see [llms.txt](https://bkortbus.gitbook.io/unreal-python-recipe-book/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bkortbus.gitbook.io/unreal-python-recipe-book/dev-conveniences/abstraction-layer.md).

# Abstraction Layer

simplifying Unreal's API

For anyone coming from Maya development, the comparison I like to give is that Unreal doesn't really have a `cmds` equivalent, Unreal's Python API is like `OpenMaya`: a direct conversion of C++ classes with minimal conveniences.

While I do write a lot of tool-specific code, I also build up convenience modules as well for various parts of the Unreal Python API, such as making a more accessible save function:

```python
from systems import EditorAssetSubsystem

def save_asset(asset, force=False) -> bool:
    """Save the provided asset or asset path"""
    if isinstance(asset, unreal.Object):
        asset = asset.get_outermost().get_path_name()
    
    return EditorAssetSubsystem.save_asset(asset, not force)
```

I can call this function with a string asset path or a loaded Unreal Object, making it more accessible to save assets elsewhere in my Python code.

My general rule of thumb is to look out for one of two conditions:

* Does a repeated task consistently require the same multiple lines to use properly?
  * some Python API functions may require additional setup to use, if used frequently enough they're solid candidates for making a convenience function for
* Could a repeated task be made more accessible?
  * `save_asset`  as an example, we could make a single function that handles any kind of common asset reference (asset path, loaded object, or AssetData object)
