{ "info": { "author": "Matt VanEseltine", "author_email": "matvan@umich.edu", "bugtrack_url": null, "classifiers": [ "Development Status :: 2 - Pre-Alpha", "Environment :: Console", "Intended Audience :: Developers", "Intended Audience :: Science/Research", "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", "Natural Language :: English", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX :: Linux", "Programming Language :: Python", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3 :: Only", "Programming Language :: SQL", "Topic :: Database", "Topic :: Scientific/Engineering", "Topic :: Software Development :: Build Tools" ], "description": "

laforge is a low-key build system for working with data.

\n\n [![License: AGPL 3.0](https://img.shields.io/pypi/l/laforge.svg?style=flat-square&color=violet)](https://www.gnu.org/licenses/agpl-3.0)\n [![Python: 3.6+](https://img.shields.io/pypi/pyversions/laforge.svg?&style=flat-square)](https://pypi.python.org/pypi/laforge)\n [![GitHub last commit](https://img.shields.io/github/last-commit/vaneseltine/laforge.svg?style=flat-square)](https://git.sr.ht/~matvan/laforge)\n [![Cat: Onigiri](https://img.shields.io/badge/cat-Onigiri-333.svg?style=flat-square)](https://raw.githubusercontent.com/vaneseltine/vaneseltine.github.io/master/Oni.jpg)\n\n---\n\n### \ud83d\udcbb Introduction\n\n*You know, I've always thought technology could solve almost any problem.*\n\n```\n$ python -m pip install laforge -q\n...\n\n$ laforge create\nCreating /home/matvan/science/build.ini\n? Creating a new laforge INI at: /home/matvan/science/build.ini\n\nCreating /home/matvan/science/build.ini\n\n? Default read directory, relative to /home/matvan/science/: ./data\n? Default write directory, relative to /home/matvan/science/: ./output\n? Default execute directory, relative to /home/matvan/science/: ./\n? SQL Distribution: SQLite\n? Database: :memory:\nNew laforge INI written at: /home/matvan/science/build.ini\nEnjoy!\n\n```\n\n*There's theory and then there's application. They don't always jibe.*\n\n```ini\n$ vim ./build.ini\n...\n\n$ cat ./build.ini\n[DEFAULT]\nread_dir: ./data\nwrite_dir: ./output\nexecute_dir: ./\ndistro: sqlite\ndatabase: :memory:\n\n# Write the contents of an Excel sheet as a SQL table\n[load_individual]\nread: 2019_indiv_data.xlsx\nwrite: raw_grp\n\n# Write the contents of a CSV as a SQL table\n[load_group]\nread: 2019_grp_data.csv\nwrite: raw_indiv\n\n# Execute a standalone SQL script; read a SQL table and save as CSV\n[do_some_things]\nexecute: do_stuff.sql\nread: laforge.demo.aggregate\nwrite: aggregate.csv\n\n# Read the result of an ad-hoc SQL query; write to an HTML table\n[peek]\nread:\n \"select top 50 *\n from demo.aggregate agg\n left join demo.raw_indiv ri\n on agg.v1 = r1.v2\n order by newid();\"\nwrite: results_peek.html\n```\n\n*Yeah, but that's imposs\u2014yes, sir.*\n\n```sh\n$ laforge build\n```\n**\u2016-)**\n\n### \ud83d\udcd3 Documentation\n\nhttps://laforge.readthedocs.io/en/latest/\n\n### \u2697\ufe0f Development\n\n*Captain, we can do it... It'll take fifteen years and a research team of a hundred.*\n\n[![Canonical repository at git.sr.ht.](https://img.shields.io/badge/canonical_repo-git.sr.ht-orange.svg?style=for-the-badge&logoWidth=0)](https://git.sr.ht/~matvan/laforge)\n\n[![Issue tracker at todo.sr.ht.](https://img.shields.io/badge/issue_tracker-todo.sr.ht-yellow.svg?style=for-the-badge&logoWidth=0)](https://todo.sr.ht/~matvan/laforge)\n\n[![Core build service at builds.sr.ht.](https://img.shields.io/badge/build_service-builds.sr.ht-green.svg?style=for-the-badge&logoWidth=0)](https://builds.sr.ht/~matvan/laforge)\n\n[![Designed with Diet Coke.](https://img.shields.io/badge/designed_with-diet_coke-5C4033.svg?style=for-the-badge&logoWidth=5)]()\n\n### \ud83e\udd16 Automation\n\n[![LGTM Alerts](https://img.shields.io/lgtm/alerts/github/vaneseltine/laforge.svg?style=for-the-badge)](https://lgtm.com/projects/g/vaneseltine/laforge/)\n\n[![PyPI dependencies analysis at libraries.io](https://img.shields.io/librariesio/release/pypi/laforge.svg?style=for-the-badge&label=libraries.io)](https://libraries.io/pypi/laforge)\n\n[![Documentation hosted on Read the Docs](https://img.shields.io/readthedocs/laforge.svg?style=for-the-badge&label=Read%20the%20Docs)](https://readthedocs.org/projects/laforge/builds/)\n\n[![Travis testing with coverage)](https://img.shields.io/travis/com/vaneseltine/laforge.svg?style=for-the-badge&label=Travis)](https://travis-ci.com/vaneseltine/laforge)\n\n[![Coveralls coverage reporting](https://img.shields.io/coveralls/github/vaneseltine/laforge.svg?style=for-the-badge)](https://coveralls.io/github/vaneseltine/laforge)\n\n### \ud83d\ude80 Downstream\n\n[![GitHub tag (latest by date)](https://img.shields.io/github/tag-date/vaneseltine/laforge.svg?label=github&style=for-the-badge)](https://github.com/vaneseltine/laforge)\n\n[![PyPI](https://img.shields.io/pypi/v/laforge.svg?style=for-the-badge)](https://pypi.python.org/pypi/laforge)\n\n### \ud83e\uddd9\u200d Author\n\n[![Matt VanEseltine](https://img.shields.io/badge/matt-vaneseltine-888.svg?style=for-the-badge&logo=linux&logoColor=fff&color=violet)](https://vaneseltine.github.io)\n\n[![matvan@umich.edu](https://img.shields.io/badge/email-matvan@umich.edu-888.svg?style=for-the-badge&logo=gmail&logoColor=fff&color=00274c)](matvan@umich.edu)\n\n[![https://git.sr.ht/~matvan](https://img.shields.io/badge/sr.ht-matvan-888.svg?style=for-the-badge&color=007bff&logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAMAAAD04JH5AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH4QIGCC8n92KyhQAAAj1QTFRFAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////anIwUQAAAL50Uk5TAAECAwQFBgcICQoLDA4PEBESExQVFhcYGRobHB0eHyAhIyQmJygpKistLzAzNDU2Nzg5Ozw9QEFDREZHSElLTE1OT1BRVFdYWVpbXF1eX2BhZGZnaGltbnBxdHV3eHp7fn+AgYKDhIWGh4iJio2TlJucnqGio6Smp6ipqqusrbCxsrO0tre4ury9vr/Cw8TFxsfIycrMzc7P0dLT1dbY2dvf4OLj5OXm5+jq6+zt7u/w8fL09fb3+Pn6+/z9/gNzyOkAAAABYktHRL6k3IPDAAAFwUlEQVQYGe3B+VtUVQAG4G9i0TQZZyA1S0JxydzDNFTUqXBfcylzS8UE21TMyjAQUQnFEi0BHQU3cAc0UGbm+9v65Zw7y70zc++dc3qenof3xZAhQ4b8T+V/uGn/kdrm1psdHTdbm2uP7Ns434//yLD5e+u7aOH+6T0ludBszGf1L5jC87rNBdDm9XXnw0wrfG71cOhQ9N0z2vTk20Ko9t5PYToQOj4FKr17IkKHwtUToMobVQN0of/rkVDik7t06c5yZC7/V1rqajq6f9vKQFlZYNW2A0cvdNPSL35kaPEDmgxerFiSjwQFZQebQzTpKkUmsg4xUX/Nijwk4V15aoAJIhVZcM13ngnatuQhJe/WNiY464VLE28xXsMCD9LyLDzLeMEiuDLzIeM0zIRNs88xTvcMuFDSx1htC+FA6XXG6pkLx0qeM8aLHdlwJGfnP4zRNw8OzexjjOaJcGzSn4zR8z4cmfiQUZF9WXAhuyLCqO4iOOC7xahni+BSWQ+jgl7YlnWeUR3FcG1qJ6MasmDXIUZdexMZGNvGqAOwaTGjrnqREd/fNERKYUvBAxqueZEhXzsNXX7Y8SsNHW8iY+M6afgZNnxKw7NiKDCtl4YA0nrjHqXIIiixjIY7I5FOFQ37oEglDZVIo+glpeYsKJJ9mdJAIVI7QenFRChT3E+pGim9F6G0AwrtohSeglR+otSWDYVygpSqkUJRmNJCKLWEUmgCkvuOUgPU8vxO6TCSev0ZpZlQ7ANKj4YhmXWUGqBcI6UVSOY8pQVQbhGlM0hiTJhCmwfKeW5QCPlh7TNKW6DBdkobYa2eQn8eNPC9pPAbLA17QaEGWtRS6MuBlfmUVkCLtZTmwspeCoN50MIXprATVuopXIQmLRROwUoXhQpoUkXhNizkU1oCTZZRyoPZh5Tyock4SnNgtolCF3TxPKKwBmb7KTRBm0sUdsPsCIWj0OY4hR9gVkthP7SppHASZs0UtkGbLyg0wqyVwkpos4FCC8xuUghAm3IK7TDroFAGbQIUgjDroFAGbQIUgjC7SSEAbcoptMOslcIqaLOBQgvMmilsgzY7KDTCrJbCAWhTReEkzI5QOAptfqTwPcz2UbgAbS5R2AWzjRS6oYvnMYXVMJtPqQCavEVpNsz8lMqgyXJKo2DhPoWD0OQwhU5YOU2hGZpcoVADK3sohLzQwh+h8CWslFBaCS3WUZoDK7nPKZyCFnUUerNh6TSFAS808L+iUANrmylthQafU1oPawVhCm0eKOcJUhgcjSTOUVoI5RZTqkMyqymdhXJNlMqRzPAnlGZDsRJKD3OR1LeUzkEtTxOlSiRXGKL0EZRaSmlwPFI4Tul6DhTKvUXpGFKZEqa0EwrtoRQqRkrVlP6ZBGUmD1A6htQm9FP6IxuK5Fyl1P8O0viahgoo8g0NB5HOyDuUImVQ4mMabo9AWgEaeqZCgel9NCyFDb/Q0DkWGXv7Lg0nYIe/i4Y2HzKUf4OGe6NhS2mEhr98yEh+Kw3hBbCpglHt45CB8TcY9RXsyjrLqM5pcG36XUadfg22eYOM6l0Glz7uY9T1UXCg6AFjHMqGCznfMMb9Qjgyo4cxLhfDsclXGePpdDg0r48x+nflwJHcPQOM0TsLjs3rYazgEtjnWXqLsZ7Oggszuhnn9w9gU0kT49yfDleKgozXuMiDtDyLmxjveiFc8jYwwY3tPqTk/zzIBPWj4FpWRYQJXtau9SEJ/7q6V0wQ/uo1ZKK0iybhlqplYxHP89byw1ciNLm3ABny/0xLjy4dr/xiQ3kgUL5hR9WPlx7T0onRyFzgDl26vRRKjKwcoAv9B0dAlcLqMB0KH3sHKk2pDtGBwWPFUG3C4Ue06WHleOgwbMWZENMarCvPhTb+jb/1MYXemvWjoVnO3J2nbtNCZ82Xc7LxH8mbs2b3DycbW9qDwfaWxpPf71o9exSGDBky5P/pX9F6dsCMuJp+AAAAAElFTkSuQmCC)](https://git.sr.ht/~matvan)\n\n\n[![https://github.com/vaneseltine](https://img.shields.io/badge/github-vaneseltine-888.svg?style=for-the-badge&logo=github&logoColor=fff&color=2b3137)](https://github.com/vaneseltine)\n\n[![https://twitter.com/vaneseltine](https://img.shields.io/badge/twitter-@vaneseltine-blue.svg?style=for-the-badge&logo=twitter&logoColor=fff&color=1da1f2)](https://twitter.com/vaneseltine)\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://git.sr.ht/~matvan/laforge", "keywords": "build data database pandas pipeline SQL SQLAlchemy workflow", "license": "AGPL-3.0-or-later", "maintainer": "", "maintainer_email": "", "name": "laforge", "package_url": "https://pypi.org/project/laforge/", "platform": "", "project_url": "https://pypi.org/project/laforge/", "project_urls": { "Homepage": "https://git.sr.ht/~matvan/laforge" }, "release_url": "https://pypi.org/project/laforge/0.1.6/", "requires_dist": [ "Click (>=7.0)", "python-dotenv (>=0.10.3)", "pandas (>=0.22)", "PyInquirer (>=1.0)", "pyparsing (>=2.3)", "SQLAlchemy (>=1.3)", "openpyxl (==2.6.2) ; extra == 'all'", "psycopg2 (>=2.8) ; extra == 'all'", "xlrd (==1.2.0) ; extra == 'all'", "pymysql (>=0.9) ; extra == 'all'", "pyodbc (>=4.0) ; extra == 'all'", "pymysql (>=0.9) ; extra == 'ci'", "xlrd (==1.2.0) ; extra == 'ci'", "openpyxl (==2.6.2) ; extra == 'ci'", "xlrd (==1.2.0) ; extra == 'excel'", "openpyxl (==2.6.2) ; extra == 'excel'", "pymysql (>=0.9) ; extra == 'mariadb'", "pyodbc (>=4.0) ; extra == 'mssql'", "pymysql (>=0.9) ; extra == 'mysql'", "psycopg2 (>=2.8) ; extra == 'postgresql'" ], "requires_python": "", "summary": "A low-key build system for working with data.", "version": "0.1.6" }, "last_serial": 5464352, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "18a6debab652086d8401e79319e90275", "sha256": "b9c181424c57a110ef553b04470b8a271b18dc584167ece151ba60c6c0cbeca4" }, "downloads": -1, "filename": "laforge-0.1.0-py3-none-any.whl", "has_sig": false, "md5_digest": "18a6debab652086d8401e79319e90275", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 28210, "upload_time": "2019-06-17T02:51:01", "url": "https://files.pythonhosted.org/packages/ee/9e/7d1a060f6ac81597d9176632c2a87880859d28ae895fa1248c73dd3739c5/laforge-0.1.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "b20fc4978510e49428c0a05d4fe546c9", "sha256": "a7cf538c0eff87285c172011f57339641b623897a0ea79e084f73c8d2da1d3b6" }, "downloads": -1, "filename": "laforge-0.1.0.tar.gz", "has_sig": false, "md5_digest": "b20fc4978510e49428c0a05d4fe546c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26772, "upload_time": "2019-06-17T02:51:05", "url": "https://files.pythonhosted.org/packages/1c/a7/b81ac9b2cdb374b0b587d7fabc7ceccf1c210bbae349db2c83baf337541a/laforge-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "7cc65ff32b192b022156e08a3744689a", "sha256": "531536ef815f20aceaad17a52df372d1d22be8ed1d000e5f49d8367148ec7e39" }, "downloads": -1, "filename": "laforge-0.1.1-py3-none-any.whl", "has_sig": false, "md5_digest": "7cc65ff32b192b022156e08a3744689a", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 27908, "upload_time": "2019-06-17T04:49:43", "url": "https://files.pythonhosted.org/packages/38/bf/463fa5e9c57b972b26c245ebd68ac379cb62bc5be5f529687a7dc46c2aa8/laforge-0.1.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "372277aea975e319afd47f88cd30b008", "sha256": "f419143ee2d33f0fbc2801bfe9b303f42c87cd8158cd65edc14df2b946d89114" }, "downloads": -1, "filename": "laforge-0.1.1.tar.gz", "has_sig": false, "md5_digest": "372277aea975e319afd47f88cd30b008", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 26546, "upload_time": "2019-06-17T04:49:55", "url": "https://files.pythonhosted.org/packages/02/15/dc745b559a33db9b7eca83c4582e735601ca42ae7a627dfcef54c7fa706f/laforge-0.1.1.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "afc92431d3fc66757d91ce2105e93f10", "sha256": "8872c1a6afe66b777bcca55e0181d6a9e8dbf9dd48f8103f1a407cca0ba6b45f" }, "downloads": -1, "filename": "laforge-0.1.3-py3-none-any.whl", "has_sig": false, "md5_digest": "afc92431d3fc66757d91ce2105e93f10", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 66755, "upload_time": "2019-06-28T02:39:21", "url": "https://files.pythonhosted.org/packages/76/b1/70706c0828fe273715e304fb36ed5665cf555f99215080eba28c59c7d2e6/laforge-0.1.3-py3-none-any.whl" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "b1bfba070b4bb44568613ecfd1505bf7", "sha256": "21e25c2cdca681ea168e4057ba46ff2101ff4036d0b5428a55d0e5b63bff2d90" }, "downloads": -1, "filename": "laforge-0.1.4-py3-none-any.whl", "has_sig": false, "md5_digest": "b1bfba070b4bb44568613ecfd1505bf7", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 66754, "upload_time": "2019-06-28T02:39:26", "url": "https://files.pythonhosted.org/packages/65/17/9f254353049f66a50ae5b9daf401747959a1aad50711217303e34a53daa6/laforge-0.1.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ca29668b2e06ea1f7dab51dfd05ce795", "sha256": "6801401b847d5d30cfede05a5adc384e923856148cca5117def404defa53f296" }, "downloads": -1, "filename": "laforge-0.1.4.tar.gz", "has_sig": false, "md5_digest": "ca29668b2e06ea1f7dab51dfd05ce795", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 47313, "upload_time": "2019-06-28T02:42:11", "url": "https://files.pythonhosted.org/packages/97/a9/4093dc339fd2e4380ec4595f3ec77f12bdeb075bf7ca1445b8a65afbe601/laforge-0.1.4.tar.gz" } ], "0.1.5": [ { "comment_text": "", "digests": { "md5": "1976f314dd91dd065109b70f061ebdd6", "sha256": "d209d6940de427c441566181755bd64be72b8e10391a48afac3b3925e4d3c4e1" }, "downloads": -1, "filename": "laforge-0.1.5-py3-none-any.whl", "has_sig": false, "md5_digest": "1976f314dd91dd065109b70f061ebdd6", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 68264, "upload_time": "2019-06-28T16:19:12", "url": "https://files.pythonhosted.org/packages/96/3d/f4602312e652eed1293f4f5f9df818cb96d258481b93719adef1b20b4eea/laforge-0.1.5-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "146b7b155155a38aa2801451f5a63eb2", "sha256": "b7720c036dfba640f28f5f94b0e17e58b7cd09374f54b197d6edb541e4804d5b" }, "downloads": -1, "filename": "laforge-0.1.5.tar.gz", "has_sig": false, "md5_digest": "146b7b155155a38aa2801451f5a63eb2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50676, "upload_time": "2019-06-28T16:19:14", "url": "https://files.pythonhosted.org/packages/d0/08/64a0d4c8dea585259acc626c61a6b2a318eff1ffb80c50ce6088ed4a0979/laforge-0.1.5.tar.gz" } ], "0.1.6": [ { "comment_text": "", "digests": { "md5": "974c5ccfbd3187e41f8cb1bed7771518", "sha256": "bdf599277c86123534cbd0bfa3cef46896dd7aad294b73a5f501fee3e8b6bee0" }, "downloads": -1, "filename": "laforge-0.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "974c5ccfbd3187e41f8cb1bed7771518", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 68276, "upload_time": "2019-06-29T04:15:20", "url": "https://files.pythonhosted.org/packages/fe/ef/14c5ec4db91a2c30e34ed5abf581d8a42c30fe9224732d66e915dc25916c/laforge-0.1.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d1e3758a2f14de2c0422f4a383ecd06", "sha256": "a440098d54d4523e8dec329f7152dae98939e0b58583062f65a5cf280b481a84" }, "downloads": -1, "filename": "laforge-0.1.6.tar.gz", "has_sig": false, "md5_digest": "0d1e3758a2f14de2c0422f4a383ecd06", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50712, "upload_time": "2019-06-29T04:15:22", "url": "https://files.pythonhosted.org/packages/11/0e/b6f2891d06ebddf11e61d52fff6531d7dd0d865227c09c667a059877fe13/laforge-0.1.6.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "974c5ccfbd3187e41f8cb1bed7771518", "sha256": "bdf599277c86123534cbd0bfa3cef46896dd7aad294b73a5f501fee3e8b6bee0" }, "downloads": -1, "filename": "laforge-0.1.6-py3-none-any.whl", "has_sig": false, "md5_digest": "974c5ccfbd3187e41f8cb1bed7771518", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 68276, "upload_time": "2019-06-29T04:15:20", "url": "https://files.pythonhosted.org/packages/fe/ef/14c5ec4db91a2c30e34ed5abf581d8a42c30fe9224732d66e915dc25916c/laforge-0.1.6-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d1e3758a2f14de2c0422f4a383ecd06", "sha256": "a440098d54d4523e8dec329f7152dae98939e0b58583062f65a5cf280b481a84" }, "downloads": -1, "filename": "laforge-0.1.6.tar.gz", "has_sig": false, "md5_digest": "0d1e3758a2f14de2c0422f4a383ecd06", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 50712, "upload_time": "2019-06-29T04:15:22", "url": "https://files.pythonhosted.org/packages/11/0e/b6f2891d06ebddf11e61d52fff6531d7dd0d865227c09c667a059877fe13/laforge-0.1.6.tar.gz" } ] }