Skip to content
Back to top
View this page
Edit this page

# Tutorial: Xonsh Projects

Bam! Suppose you want to get beyond scripting and write a whole library, utility, or other big project in xonsh. Here is how you do that. Spoiler alert: it is easy, powerful, and fun!

## Overview

Xonsh is fully interoperable with Python. Writing a xonsh library is very similar to writing a Python library, using all of the same tooling and infrastructure for packaging pure Python code.

## Structure

Xonsh modules are written in xonsh files (`*.xsh`), side-by-side with Python files (`*.py`). Suppose we have a package called `mypkg` which uses xonsh files. Here is a sample file system layout would be:

    |- mypkg/
       |- __init__.py    # a regular package with an init file
       |- other.py       # not a xonsh file
       |- show.py        # "mypkg.show", full module name
       |- tell.xsh       # "mypkg.tell", full module name
       |- subpkg/
          |- __init__.py
          |- a.py      # "mypkg.subpkg.a", full module name
          |- b.xsh     # "mypkg.subpkg.b", full module name

To ensure that these files are installed, you need to provide the appropriate information in `setup.py` file for your project. For the above structure, this looks like the following.

setup.py:

    setup(
        packages=['mypkg', 'mypkg.subpkg'],
        package_dir={'mypkg': 'mypkg', 'mypkg.subpkg': 'mypkg/subpkg'},
        package_data={'mypkg': ['*.xsh'], 'mypkg.subpkg': ['*.xsh']},
    )

With this, the xonsh code will be installed and included in any source distribution you create!

## Setting up xonsh sessions

Xonsh code requires a `XonshSession` to exist as `builtins.__xonsh__` and for be that object to be setup correctly. This can be quite a bit of work and the exact setup depends on the execution context. To simplify the process of constructing the session properly, xonsh provides the `xonsh.main.setup()` function specifically for use in 3rd party packages.

While `xonsh.main.setup()` is safely re-entrant, it is a good idea to add the following snippet to the root-level `__init__.py` of your project. With the `mypkg` example above, the session setup is as follows:

`mypkg/__init__.py`

    from xonsh.main import setup
    setup()
    del setup

Enjoy!