{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Running XULE in Arelle \n", "This interactive environment copies the [free, open-source XULE plugin](https://github.com/xbrlus/xule/) to a working Python environment with [Arelle](https://pypi.org/project/arelle-release/) plus [additional packages](https://raw.githubusercontent.com/xbrlus/xule/jupyter/environment.yml). Click the code cell below (gray background) to bring it in focus, then click the run button above to add and confirm XULE is ready. **The asterisk to the left of the cell indicates the cell is queued/processing**. " ] }, { "cell_type": "code", "execution_count": null, "id": "f0ee42f6", "metadata": { "cellView": "form", "tags": [ "hide-cell", "hide_code" ] }, "outputs": [], "source": [ "import os, shutil, sys, site, platform\n", "print('Please wait while Arelle, XULE and some helper packages are installed. \\nA XULE version message appears below when the environment is ready.')\n", "\n", "# In this example, Arelle and aniso are required to use XULE - get Arelle release details from GitHub (https://github.com/Arelle/arelle/releases).\n", "# Use %pip -q install git+https://git@github.com/Arelle/arelle.git@master to use Arelle's development release\n", "%pip -q install Arelle-release==2.30.11\n", "%pip -q install aniso8601==9.0.1\n", "\n", "# 1) locate Arelle's plugin directory (do not modify this location); remove temp and xuledir if they exist\n", "plugindir = site.getsitepackages()[0] + '/arelle/plugin/'\n", "xuledir = plugindir + 'xule/'\n", "xodeldir = plugindir + 'xodel/'\n", "serializerdir = plugindir + 'serializer/'\n", "SimpleXBRLModeldir = plugindir + 'SimpleXBRLModel/'\n", "temp = plugindir + 'temp/'\n", "tempxule = temp + 'plugin/xule/'\n", "tempxodel = temp + 'plugin/xodel/'\n", "tempserializer = temp + 'plugin/serializer/'\n", "tempSimpleXBRLModel = temp + 'plugin/SimpleXBRLModel/'\n", "if os.path.exists(temp):\n", " if os.path.isdir(temp):\n", " os.remove(plugindir + 'semanticHash.py')\n", " shutil.rmtree(xuledir)\n", " shutil.rmtree(xodeldir)\n", " shutil.rmtree(serializerdir)\n", " shutil.rmtree(SimpleXBRLModeldir)\n", " shutil.rmtree(temp)\n", "else: ''\n", "os.chdir(plugindir)\n", "\n", "# 2) copy a XULE release from GitHub (https://github.com/xbrlus/xule/releases) to plugin directory\n", "!git clone --quiet --depth=1 --branch 30041 --single-branch https://github.com/xbrlus/xule.git temp &> /dev/null\n", "shutil.move(temp + 'plugin/semanticHash.py', plugindir)\n", "shutil.move(tempxule, xuledir)\n", "shutil.move(tempxodel, xodeldir)\n", "shutil.move(tempserializer, serializerdir)\n", "shutil.move(tempSimpleXBRLModel, SimpleXBRLModeldir)\n", "\n", "# 3) confirm XULE (change -v to -h and re-run to see help contents for Arelle and XULE)\n", "!arelleCmdLine --plugins 'xule' -v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 1. Define a XULE Expression\n", "The cell below is the contents of a XULE 'file' called sample.xule **which starts on the line below %%writefile** - *a Jupyter-specific command* that saves the cell's contents as a file when the cell is run.\n", "\n", "Click the code cell below then **use 'Run All Below' from Jupyter's Cell menu** to save and run XULE with a single click (NB: after the cell is run once, toggling **%%writefile** to **%load** will display the contents of the sample.xule file in the cell). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%%writefile 'sample.xule'\n", "/** add constants and namespaces below **/\n", "\n", "/** modify rule below **/\n", "output example\n", "{@}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### 2. Run XULE against an XBRL report\n", "The cell below compiles the sample.xule file above (the `{@}` XULE expression returns all facts for an XBRL report) and runs the .zip against the instance document listed in the command (NB: run the first code cell in this notebook with the -h switch instead of -v to get configuration paramters for the command). " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "!arelleCmdLine -f \"https://www.sec.gov/Archives/edgar/data/1753673/000121390022027184/f20f2021_scienjoyhold.htm\" \\\n", "--plugins \"xule | transforms/SEC\" --xule-compile \"sample.xule\" --xule-run --xule-rule-set \"sample.zip\" \\\n", "--httpUserAgent \"XULE-Arelle (xbrl.us; support@xbrl.us)\" --logFormat=\"[%(messageCode)s] %(message)s\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "Any **[example]** details listed above were found in the report ('example' is the default name of the output in the sample.xule file above). Modify and re-run the _1. Define_ and _2. Run_ cells, or change and re-run the report in the _2. Run_ cell to get different results.\n", "\n" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython" }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python" }, "vscode": { "interpreter": {} } }, "nbformat": 4, "nbformat_minor": 5 }