.. image:: https://img.shields.io/pypi/v/pycomex.svg
:target: https://pypi.python.org/pypi/pycomex
.. image:: https://readthedocs.org/projects/pycomex/badge/?version=latest
:target: https://pycomex.readthedocs.io/en/latest/?version=latest
:alt: Documentation Status
=============================================
☄️ PyComex - Python Computational Experiments
=============================================
Microframework to improve the experience of running and managing archival records of computational
experiments, such as machine learning and data science experiments, in Python.
===========
🔥 Features
===========
* Automatically create (nested) folder structure for results of each run of an experiment
* Simply attach metadata such as performance metrics to experiment object and they will be automatically
stored as JSON file
* Easily attach file artifacts such as ``matplotlib`` figures to experiment records
* Log messages to stdout as well as permanently store into log file
* Ready-to-use automatically generated boilerplate code for the analysis and post-processing of
experiment data after experiments have terminated.
* Experiment inheritance: Experiment modules can inherit from other modules and extend their functionality
via parameter overwrites and hooks!
==========================
📦 Installation by Package
==========================
Install the stable version with ``pip``
.. code-block:: console
pip3 install pycomex
=========================
📦 Installation by Source
=========================
Or the most recent development version by cloning the source:
.. code-block:: console
git clone https://github.com/the16thpythonist/pycomex.git
and then installing with either pip
.. code-block:: console
cd pycomex
pip3 install -e .
or poetry
.. code-block:: console
cd pycomex
poetry install
=============
🚀 Quickstart
=============
Each computational experiment has to be bundled as a standalone python module. Important experiment
parameters are placed at the top of this module. All variable names written in upper case will automatically
be detected as parameters of the experiment.
The actual implementation of the experiment execution is placed into a single file which will have to be
decorated with the ``Experiment`` decorator.
Upon execution the experiment, a new archive folder is automatically created. This archive folder can
be used to store all the file artifacts that are created during the experiment.
Some artifacts are stored automatically by default, such as a JSON file containing all data stored in the
main experiment storage, a snapshot of the experiment module and more...
Archiving of metadata, file artifacts and error handling is automatically managed on context exit.
.. code-block:: python
# quickstart.py
"""
This doc string will be saved as the "description" meta data of the experiment records
"""
import os
from pycomex.functional.experiment import Experiment
from pycomex.utils import folder_path, file_namespace
# Experiment parameters can simply be defined as uppercase global variables.
# These are automatically detected and can possibly be overwritten in command
# line invocation
HELLO = "hello "
WORLD = "world!"
# There are certain special parameters which will be detected by the experiment
# such as this, which will put the experiment into debug mode.
# That means instead of creating a new archive for every execution, it will always
# create/overwrite the "debug" archive folder.
__DEBUG__ = True
# An experiment is essentially a function. All of the code that constitutes
# one experiment should ultimately be called from this one function...
# The main experiment function has to be decorated with the "Experiment"
# decorator, which needs three main arguments:
# - base_path: The absolute string path to an existing FOLDER, where the
# archive structure should be created
# - namespace: This is a relative path which defines the concrete folder
# structure of the specific archive folder for this specific experiment
# - glob: The globals() dictionary for the current file
@Experiment(base_path=os.getcwd(),
namespace='results/quickstart',
glob=globals())
def experiment(e: Experiment):
# Internally saved into automatically created nested dict
# {'strings': {'hello_world': '...'}}
e["strings/hello_world"] = HELLO + WORLD
# Alternative to "print". Message is printed to stdout as well as
# recorded to log file
e.log("some debug message")
# Automatically saves text file artifact to the experiment record folder
file_name = "hello_world.txt"
e.commit_raw(file_name, HELLO + WORLD)
# e.commit_fig(file_name, fig)
# e.commit_png(file_name, image)
# ...
@experiment.analysis
def analysis(e: Experiment):
# And we can access all the internal fields of the experiment object
# and the experiment parameters here!
print(HELLO, WORLD)
print(e['strings/hello_world'])
# logging will print to stdout but not modify the log file
e.log('analysis done')
# This needs to be put at the end of the experiment. This method will
# then actually execute the main experiment code defined in the function
# above.
# NOTE: The experiment will only be run if this module is directly
# executed (__name__ == '__main__'). Otherwise the experiment will NOT
# be executed, which implies that the experiment module can be imported
# from somewhere else without triggering experiment execution!
experiment.run_if_main()
This example would create the following folder structure:
.. code-block:: python
cwd
|- results
|- quickstart
|- debug
|+ experiment_out.log # Contains all the log messages printed by experiment
|+ experiment_meta.json # Meta information about the experiment
|+ experiment_data.json # All the data that was added to the internal exp. dict
|+ hello_world.txt # Text artifact that was committed to the experiment
|+ code.py # Copy of the original experiment python module
|+ analysis.py # boilerplate code to get started with analysis of results
The ``analysis.py`` file is of special importance. It is created as a boilerplate starting
place for additional code, which performs analysis or post processing on the results of the experiment.
This can for example be used to transform data into a different format or create plots for visualization.
Specifically note these two aspects:
1. The analysis file contains all of the code which was defined in the ``analysis`` function of the
original experiment file! This code snippet is automatically transferred at the end of the experiment.
2. The analysis file actually imports the snapshot copy of the original experiment file. This does not
trigger the experiment to be executed again! The ``Experiment`` instance automatically notices that it
is being imported and not explicitly executed. It will also populate all of it's internal attributes
from the persistently saved data in ``experiment_data.json``, which means it is still possible to access
all the data of the experiment without having to execute it again!
.. code-block:: python
# analysis.py
# [...] imports omitted
from code import *
from pycomex.functional.experiment import Experiment
PATH = pathlib.Path(__file__).parent.absolute()
# "Experiment.load" is used to load the the experiment data from the
# archive. it returns an "Experiment" object which will act exactly the
# same way as if the experiment had just finished it's execution!
CODE_PATH = os.path.join(PATH, 'code.py')
experiment = Experiment.load(CODE_PATH)
experiment.analyses = []
# All of the following code is automatically extracted from main
# experiment module itself and can now be edited and re-executed.
# Re-execution of this analysis.py file will not trigger an
# execution of the experiment but all the stored results will be
# available anyways!
@experiment.analysis
def analysis(e: Experiment):
# And we can access all the internal fields of the experiment
# object and the experiment parameters here!
print(HELLO, WORLD)
print(e['strings/hello_world'])
# logging will print to stdout but not modify the log file
e.info('analysis done')
# This method will execute only the analysis code!
experiment.execute_analyses()
For an introduction to more advanced features take a look at the examples in
``pycomex/examples`` ( https://github.com/the16thpythonist/pycomex/tree/master/pycomex/examples )
================
📖 Documentation
================
Unfortunately, there exists no dedicated documentation of the project yet. However, some additional details on some
key topics can be found in the ``DOCUMENTATION.rst`` file.
Aside from that, the ``pycomex/examples`` ( https://github.com/the16thpythonist/pycomex/tree/master/pycomex/examples ) folder
contains some example modules which illustrate some of the key features of the framework by practical example.
==========
🤝 Credits
==========
This package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.
.. _Cookiecutter: https://github.com/audreyr/cookiecutter
.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage
Raw data
{
"_id": null,
"home_page": null,
"name": "pycomex",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": "Jonas Teufel <jonseb1998@gmail.com>",
"keywords": "academia, computational experiments, data science, maschine learning",
"author": null,
"author_email": "Jonas Teufel <jonseb1998@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/db/78/f83643c5100f095c3f3b8bd48912a714119c1d20f3be156e914ed5751380/pycomex-0.14.1.tar.gz",
"platform": null,
"description": ".. image:: https://img.shields.io/pypi/v/pycomex.svg\n :target: https://pypi.python.org/pypi/pycomex\n\n.. image:: https://readthedocs.org/projects/pycomex/badge/?version=latest\n :target: https://pycomex.readthedocs.io/en/latest/?version=latest\n :alt: Documentation Status\n\n=============================================\n\u2604\ufe0f PyComex - Python Computational Experiments\n=============================================\n\nMicroframework to improve the experience of running and managing archival records of computational\nexperiments, such as machine learning and data science experiments, in Python.\n\n===========\n\ud83d\udd25 Features\n===========\n\n* Automatically create (nested) folder structure for results of each run of an experiment\n* Simply attach metadata such as performance metrics to experiment object and they will be automatically\n stored as JSON file\n* Easily attach file artifacts such as ``matplotlib`` figures to experiment records\n* Log messages to stdout as well as permanently store into log file\n* Ready-to-use automatically generated boilerplate code for the analysis and post-processing of\n experiment data after experiments have terminated.\n* Experiment inheritance: Experiment modules can inherit from other modules and extend their functionality\n via parameter overwrites and hooks!\n\n==========================\n\ud83d\udce6 Installation by Package\n==========================\n\nInstall the stable version with ``pip``\n\n.. code-block:: console\n\n pip3 install pycomex\n\n=========================\n\ud83d\udce6 Installation by Source\n=========================\n\nOr the most recent development version by cloning the source:\n\n.. code-block:: console\n\n git clone https://github.com/the16thpythonist/pycomex.git\n\nand then installing with either pip \n\n.. code-block:: console\n\n cd pycomex\n pip3 install -e .\n\nor poetry\n\n.. code-block:: console\n\n cd pycomex\n poetry install\n\n=============\n\ud83d\ude80 Quickstart\n=============\n\nEach computational experiment has to be bundled as a standalone python module. Important experiment\nparameters are placed at the top of this module. All variable names written in upper case will automatically\nbe detected as parameters of the experiment.\n\nThe actual implementation of the experiment execution is placed into a single file which will have to be\ndecorated with the ``Experiment`` decorator.\n\nUpon execution the experiment, a new archive folder is automatically created. This archive folder can\nbe used to store all the file artifacts that are created during the experiment.\nSome artifacts are stored automatically by default, such as a JSON file containing all data stored in the\nmain experiment storage, a snapshot of the experiment module and more...\n\nArchiving of metadata, file artifacts and error handling is automatically managed on context exit.\n\n.. code-block:: python\n\n # quickstart.py\n \"\"\"\n This doc string will be saved as the \"description\" meta data of the experiment records\n \"\"\"\n import os\n from pycomex.functional.experiment import Experiment\n from pycomex.utils import folder_path, file_namespace\n\n # Experiment parameters can simply be defined as uppercase global variables.\n # These are automatically detected and can possibly be overwritten in command\n # line invocation\n HELLO = \"hello \"\n WORLD = \"world!\"\n\n # There are certain special parameters which will be detected by the experiment\n # such as this, which will put the experiment into debug mode.\n # That means instead of creating a new archive for every execution, it will always\n # create/overwrite the \"debug\" archive folder.\n __DEBUG__ = True\n\n # An experiment is essentially a function. All of the code that constitutes\n # one experiment should ultimately be called from this one function...\n\n # The main experiment function has to be decorated with the \"Experiment\"\n # decorator, which needs three main arguments:\n # - base_path: The absolute string path to an existing FOLDER, where the\n # archive structure should be created\n # - namespace: This is a relative path which defines the concrete folder\n # structure of the specific archive folder for this specific experiment\n # - glob: The globals() dictionary for the current file\n @Experiment(base_path=os.getcwd(),\n namespace='results/quickstart',\n glob=globals())\n def experiment(e: Experiment):\n # Internally saved into automatically created nested dict\n # {'strings': {'hello_world': '...'}}\n e[\"strings/hello_world\"] = HELLO + WORLD\n\n # Alternative to \"print\". Message is printed to stdout as well as\n # recorded to log file\n e.log(\"some debug message\")\n\n # Automatically saves text file artifact to the experiment record folder\n file_name = \"hello_world.txt\"\n e.commit_raw(file_name, HELLO + WORLD)\n # e.commit_fig(file_name, fig)\n # e.commit_png(file_name, image)\n # ...\n\n\n @experiment.analysis\n def analysis(e: Experiment):\n # And we can access all the internal fields of the experiment object\n # and the experiment parameters here!\n print(HELLO, WORLD)\n print(e['strings/hello_world'])\n # logging will print to stdout but not modify the log file\n e.log('analysis done')\n\n\n # This needs to be put at the end of the experiment. This method will\n # then actually execute the main experiment code defined in the function\n # above.\n # NOTE: The experiment will only be run if this module is directly\n # executed (__name__ == '__main__'). Otherwise the experiment will NOT\n # be executed, which implies that the experiment module can be imported\n # from somewhere else without triggering experiment execution!\n experiment.run_if_main()\n\n\nThis example would create the following folder structure:\n\n.. code-block:: python\n\n cwd\n |- results\n |- quickstart\n |- debug\n |+ experiment_out.log # Contains all the log messages printed by experiment\n |+ experiment_meta.json # Meta information about the experiment\n |+ experiment_data.json # All the data that was added to the internal exp. dict\n |+ hello_world.txt # Text artifact that was committed to the experiment\n |+ code.py # Copy of the original experiment python module\n |+ analysis.py # boilerplate code to get started with analysis of results\n\n\nThe ``analysis.py`` file is of special importance. It is created as a boilerplate starting\nplace for additional code, which performs analysis or post processing on the results of the experiment.\nThis can for example be used to transform data into a different format or create plots for visualization.\n\nSpecifically note these two aspects:\n\n1. The analysis file contains all of the code which was defined in the ``analysis`` function of the\n original experiment file! This code snippet is automatically transferred at the end of the experiment.\n2. The analysis file actually imports the snapshot copy of the original experiment file. This does not\n trigger the experiment to be executed again! The ``Experiment`` instance automatically notices that it\n is being imported and not explicitly executed. It will also populate all of it's internal attributes\n from the persistently saved data in ``experiment_data.json``, which means it is still possible to access\n all the data of the experiment without having to execute it again!\n\n.. code-block:: python\n\n # analysis.py\n\n # [...] imports omitted\n from code import *\n from pycomex.functional.experiment import Experiment\n\n PATH = pathlib.Path(__file__).parent.absolute()\n # \"Experiment.load\" is used to load the the experiment data from the\n # archive. it returns an \"Experiment\" object which will act exactly the\n # same way as if the experiment had just finished it's execution!\n CODE_PATH = os.path.join(PATH, 'code.py')\n experiment = Experiment.load(CODE_PATH)\n experiment.analyses = []\n\n # All of the following code is automatically extracted from main\n # experiment module itself and can now be edited and re-executed.\n # Re-execution of this analysis.py file will not trigger an\n # execution of the experiment but all the stored results will be\n # available anyways!\n @experiment.analysis\n def analysis(e: Experiment):\n # And we can access all the internal fields of the experiment\n # object and the experiment parameters here!\n print(HELLO, WORLD)\n print(e['strings/hello_world'])\n # logging will print to stdout but not modify the log file\n e.info('analysis done')\n\n\n # This method will execute only the analysis code!\n experiment.execute_analyses()\n\n\nFor an introduction to more advanced features take a look at the examples in\n``pycomex/examples`` ( https://github.com/the16thpythonist/pycomex/tree/master/pycomex/examples )\n\n================\n\ud83d\udcd6 Documentation\n================\n\nUnfortunately, there exists no dedicated documentation of the project yet. However, some additional details on some \nkey topics can be found in the ``DOCUMENTATION.rst`` file.\n\nAside from that, the ``pycomex/examples`` ( https://github.com/the16thpythonist/pycomex/tree/master/pycomex/examples ) folder \ncontains some example modules which illustrate some of the key features of the framework by practical example.\n\n==========\n\ud83e\udd1d Credits\n==========\n\nThis package was created with Cookiecutter_ and the `audreyr/cookiecutter-pypackage`_ project template.\n\n.. _Cookiecutter: https://github.com/audreyr/cookiecutter\n.. _`audreyr/cookiecutter-pypackage`: https://github.com/audreyr/cookiecutter-pypackage\n",
"bugtrack_url": null,
"license": "MIT License",
"summary": "Python Computational Experiments",
"version": "0.14.1",
"project_urls": null,
"split_keywords": [
"academia",
" computational experiments",
" data science",
" maschine learning"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "45a6c88ef0f2e0dd4b2290209d981d85286748ec40d5fd9e9ae69509eca3f033",
"md5": "5e452671456c41fa1c872c2a495b20cc",
"sha256": "43c85a2ae4f10d104052529047c5958cff2ac4f069b8b5521acc59dd766f22df"
},
"downloads": -1,
"filename": "pycomex-0.14.1-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "5e452671456c41fa1c872c2a495b20cc",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 87217,
"upload_time": "2024-11-10T10:51:18",
"upload_time_iso_8601": "2024-11-10T10:51:18.617034Z",
"url": "https://files.pythonhosted.org/packages/45/a6/c88ef0f2e0dd4b2290209d981d85286748ec40d5fd9e9ae69509eca3f033/pycomex-0.14.1-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "db78f83643c5100f095c3f3b8bd48912a714119c1d20f3be156e914ed5751380",
"md5": "72d6613efc920fff7b62bc44291e2932",
"sha256": "58d4ef116012fc6e44a68020a78cd6a38b16adc5936d93c582f9bc054a1a9974"
},
"downloads": -1,
"filename": "pycomex-0.14.1.tar.gz",
"has_sig": false,
"md5_digest": "72d6613efc920fff7b62bc44291e2932",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 327476,
"upload_time": "2024-11-10T10:51:20",
"upload_time_iso_8601": "2024-11-10T10:51:20.951562Z",
"url": "https://files.pythonhosted.org/packages/db/78/f83643c5100f095c3f3b8bd48912a714119c1d20f3be156e914ed5751380/pycomex-0.14.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-11-10 10:51:20",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "pycomex"
}