From 04221319c0c2c555c8b657239ffcd04bbf7c9cfb Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Fri, 6 May 2022 06:40:40 +0100 Subject: [PATCH 01/14] build(pyproject.toml): add ipython support Adds ipython-sql and ipython as dependencies. The goal is to wrap the former and pass it parsed prql. --- poetry.lock | 256 ++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 2 + 2 files changed, 257 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 06d2d9f..7ce011e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -6,6 +6,14 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "appnope" +version = "0.1.3" +description = "Disable App Nap on macOS >= 10.9" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "argcomplete" version = "1.12.3" @@ -67,6 +75,14 @@ python-versions = ">=3.6" [package.dependencies] pytz = ">=2015.7" +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "black" version = "22.3.0" @@ -212,6 +228,14 @@ category = "dev" optional = false python-versions = ">=3.6" +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "distlib" version = "0.3.4" @@ -417,6 +441,63 @@ category = "dev" optional = false python-versions = "*" +[[package]] +name = "ipython" +version = "7.33.0" +description = "IPython: Productive Interactive Computing" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" +pygments = "*" +setuptools = ">=18.5" +traitlets = ">=4.2" + +[package.extras] +all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] +doc = ["Sphinx (>=1.3)"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["notebook", "ipywidgets"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] + +[[package]] +name = "ipython-genutils" +version = "0.2.0" +description = "Vestigial utilities from IPython" +category = "main" +optional = false +python-versions = "*" + +[[package]] +name = "ipython-sql" +version = "0.4.0" +description = "RDBMS access via IPython" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +ipython = ">=1.0" +ipython-genutils = ">=0.1.0" +prettytable = "<1" +six = "*" +sqlalchemy = ">=0.6.7" +sqlparse = "*" + [[package]] name = "isort" version = "5.10.1" @@ -431,6 +512,21 @@ requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] plugins = ["setuptools"] +[[package]] +name = "jedi" +version = "0.18.1" +description = "An autocompletion tool for Python that can be used for text editors." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +parso = ">=0.8.0,<0.9.0" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] + [[package]] name = "jinja2" version = "3.1.2" @@ -475,6 +571,17 @@ category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "matplotlib-inline" +version = "0.1.3" +description = "Inline Matplotlib backend for Jupyter" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +traitlets = "*" + [[package]] name = "mccabe" version = "0.6.1" @@ -652,6 +759,18 @@ pytz = ">=2020.1" [package.extras] test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + [[package]] name = "pathspec" version = "0.9.0" @@ -660,6 +779,25 @@ category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +[[package]] +name = "pexpect" +version = "4.8.0" +description = "Pexpect allows easy control of interactive console applications." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "platformdirs" version = "2.5.2" @@ -712,6 +850,14 @@ pyyaml = ">=5.1" toml = "*" virtualenv = ">=20.0.8" +[[package]] +name = "prettytable" +version = "0.7.2" +description = "A simple Python library for easily displaying tabular data in a visually appealing ASCII table format." +category = "main" +optional = false +python-versions = "*" + [[package]] name = "prompt-toolkit" version = "3.0.29" @@ -731,6 +877,14 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "py" version = "1.11.0" @@ -969,6 +1123,20 @@ Click = ">=6.0" dparse = ">=0.5.1" packaging = "*" requests = "*" +setuptools = "*" + +[[package]] +name = "setuptools" +version = "62.1.0" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-enabler (>=1.0.1)", "pytest-perf", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "wheel", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "jaraco.path (>=3.2.0)", "build", "filelock (>=3.4.0)", "pip-run (>=8.8)", "ini2toml[lite] (>=0.9)", "tomli-w (>=1.0.0)", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy (>=0.9.1)"] +testing-integration = ["pytest", "pytest-xdist", "pytest-enabler", "virtualenv (>=13.0.0)", "tomli", "wheel", "jaraco.path (>=3.2.0)", "jaraco.envs (>=2.2)", "build", "filelock (>=3.4.0)"] [[package]] name = "six" @@ -1004,6 +1172,7 @@ Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" requests = ">=2.5.0" +setuptools = "*" snowballstemmer = ">=1.1" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" @@ -1136,6 +1305,14 @@ postgresql_psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql (<1)", "pymysql"] sqlcipher = ["sqlcipher3-binary"] +[[package]] +name = "sqlparse" +version = "0.4.2" +description = "A non-validating SQL parser." +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "termcolor" version = "1.1.0" @@ -1168,6 +1345,17 @@ category = "dev" optional = false python-versions = ">=3.6,<4.0" +[[package]] +name = "traitlets" +version = "5.1.1" +description = "Traitlets Python configuration system" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest"] + [[package]] name = "typed-ast" version = "1.5.3" @@ -1257,13 +1445,17 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7.1" -content-hash = "1074cdf39dbd671061b90ba381fe600072705a323efeb474b1b4ab2f36d5caf1" +content-hash = "f6bbadeb4b9adf2c027c5c2c152a22ed58080728475f1de43dd3ad3e7edb53d9" [metadata.files] alabaster = [ {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, ] +appnope = [ + {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, + {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, +] argcomplete = [ {file = "argcomplete-1.12.3-py2.py3-none-any.whl", hash = "sha256:291f0beca7fd49ce285d2f10e4c1c77e9460cf823eef2de54df0c0fec88b0d81"}, {file = "argcomplete-1.12.3.tar.gz", hash = "sha256:2c7dbffd8c045ea534921e63b0be6fe65e88599990d8dc408ac8c542b72a5445"}, @@ -1284,6 +1476,10 @@ babel = [ {file = "Babel-2.10.1-py3-none-any.whl", hash = "sha256:3f349e85ad3154559ac4930c3918247d319f21910d5ce4b25d439ed8693b98d2"}, {file = "Babel-2.10.1.tar.gz", hash = "sha256:98aeaca086133efb3e1e2aad0396987490c8425929ddbcfe0550184fdc54cd13"}, ] +backcall = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] black = [ {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, @@ -1392,6 +1588,10 @@ decli = [ {file = "decli-0.5.2-py3-none-any.whl", hash = "sha256:d3207bc02d0169bf6ed74ccca09ce62edca0eb25b0ebf8bf4ae3fb8333e15ca0"}, {file = "decli-0.5.2.tar.gz", hash = "sha256:f2cde55034a75c819c630c7655a844c612f2598c42c21299160465df6ad463ad"}, ] +decorator = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] distlib = [ {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"}, @@ -1521,10 +1721,27 @@ iniconfig = [ {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, ] +ipython = [ + {file = "ipython-7.33.0-py3-none-any.whl", hash = "sha256:916a3126896e4fd78dd4d9cf3e21586e7fd93bae3f1cd751588b75524b64bf94"}, + {file = "ipython-7.33.0.tar.gz", hash = "sha256:bcffb865a83b081620301ba0ec4d95084454f26b91d6d66b475bff3dfb0218d4"}, +] +ipython-genutils = [ + {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, + {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, +] +ipython-sql = [ + {file = "ipython-sql-0.4.0.tar.gz", hash = "sha256:3e888e59bf57277cbd6f383cb232858b2d7c71219e5749257128f16d9857e46c"}, + {file = "ipython_sql-0.4.0-py3-none-any.whl", hash = "sha256:7f93dbde77417af6647543558f7c71a90007e68d1c646868e74f4482415000c7"}, + {file = "ipython_sql-0.4.0-py3.8.egg", hash = "sha256:57b5be9f27809cdcc9c20e1077e0a5c5a9d7e4ae6328cbb83b8bede160b819e9"}, +] isort = [ {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, ] +jedi = [ + {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, + {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, +] jinja2 = [ {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, @@ -1575,6 +1792,10 @@ markupsafe = [ {file = "MarkupSafe-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:46d00d6cfecdde84d40e572d63735ef81423ad31184100411e6e3388d405e247"}, {file = "MarkupSafe-2.1.1.tar.gz", hash = "sha256:7f91197cc9e48f989d12e4e6fbc46495c446636dfc81b9ccf50bb0ec74b91d4b"}, ] +matplotlib-inline = [ + {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, + {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, +] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, @@ -1730,10 +1951,22 @@ pandas = [ {file = "pandas-1.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:09d8be7dd9e1c4c98224c4dfe8abd60d145d934e9fc1f5f411266308ae683e6a"}, {file = "pandas-1.4.2.tar.gz", hash = "sha256:92bc1fc585f1463ca827b45535957815b7deb218c549b7c18402c322c7549a12"}, ] +parso = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, ] +pexpect = [ + {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, + {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, +] +pickleshare = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] platformdirs = [ {file = "platformdirs-2.5.2-py3-none-any.whl", hash = "sha256:027d8e83a2d7de06bbac4e5ef7e023c02b863d7ea5d079477e722bb41ab25788"}, {file = "platformdirs-2.5.2.tar.gz", hash = "sha256:58c8abb07dcb441e6ee4b11d8df0ac856038f944ab98b7be6b27b2a3c7feef19"}, @@ -1750,6 +1983,11 @@ pre-commit = [ {file = "pre_commit-2.18.1-py2.py3-none-any.whl", hash = "sha256:02226e69564ebca1a070bd1f046af866aa1c318dbc430027c50ab832ed2b73f2"}, {file = "pre_commit-2.18.1.tar.gz", hash = "sha256:5d445ee1fa8738d506881c5d84f83c62bb5be6b2838e32207433647e8e5ebe10"}, ] +prettytable = [ + {file = "prettytable-0.7.2.tar.bz2", hash = "sha256:853c116513625c738dc3ce1aee148b5b5757a86727e67eff6502c7ca59d43c36"}, + {file = "prettytable-0.7.2.tar.gz", hash = "sha256:2d5460dc9db74a32bcc8f9f67de68b2c4f4d2f01fa3bd518764c69156d9cacd9"}, + {file = "prettytable-0.7.2.zip", hash = "sha256:a53da3b43d7a5c229b5e3ca2892ef982c46b7923b51e98f0db49956531211c4f"}, +] prompt-toolkit = [ {file = "prompt_toolkit-3.0.29-py3-none-any.whl", hash = "sha256:62291dad495e665fca0bda814e342c69952086afb0f4094d0893d357e5c78752"}, {file = "prompt_toolkit-3.0.29.tar.gz", hash = "sha256:bd640f60e8cecd74f0dc249713d433ace2ddc62b65ee07f96d358e0b152b6ea7"}, @@ -1760,6 +1998,10 @@ prql-python = [ {file = "prql_python-0.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:04bbb41e9b7dc6b4727972c8bc27e3b00fdbf42a842184c6cebf4cda9b47dcac"}, {file = "prql_python-0.0.2.tar.gz", hash = "sha256:2b70ccdb99cd47b26b9b54836d7bc9b3edc37d554befb406efc39b78fac7e41b"}, ] +ptyprocess = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, @@ -1865,6 +2107,10 @@ safety = [ {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, ] +setuptools = [ + {file = "setuptools-62.1.0-py3-none-any.whl", hash = "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8"}, + {file = "setuptools-62.1.0.tar.gz", hash = "sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592"}, +] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, @@ -1943,6 +2189,10 @@ sqlalchemy = [ {file = "SQLAlchemy-1.4.36-cp39-cp39-win_amd64.whl", hash = "sha256:cb441ca461bf97d00877b607f132772644b623518b39ced54da433215adce691"}, {file = "SQLAlchemy-1.4.36.tar.gz", hash = "sha256:64678ac321d64a45901ef2e24725ec5e783f1f4a588305e196431447e7ace243"}, ] +sqlparse = [ + {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, + {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, +] termcolor = [ {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, ] @@ -1958,6 +2208,10 @@ tomlkit = [ {file = "tomlkit-0.10.2-py3-none-any.whl", hash = "sha256:905cf92c2111ef80d355708f47ac24ad1b6fc2adc5107455940088c9bbecaedb"}, {file = "tomlkit-0.10.2.tar.gz", hash = "sha256:30d54c0b914e595f3d10a87888599eab5321a2a69abc773bbefff51599b72db6"}, ] +traitlets = [ + {file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"}, + {file = "traitlets-5.1.1.tar.gz", hash = "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7"}, +] typed-ast = [ {file = "typed_ast-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ad3b48cf2b487be140072fb86feff36801487d4abb7382bb1929aaac80638ea"}, {file = "typed_ast-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:542cd732351ba8235f20faa0fc7398946fe1a57f2cdb289e5497e1e7f48cfedb"}, diff --git a/pyproject.toml b/pyproject.toml index b67c47b..eee487f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,6 +36,8 @@ numpy = [ {version = "^1.22.3", python = "^3.8"} ] prql-python = "^0" +ipython-sql = "^0.4.0" +ipython = "7.33.0" [tool.poetry.dev-dependencies] pytest = "^7.0.1" From 2401f0190b136b6ddb77c48159c4064b3edbe377 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Fri, 6 May 2022 07:58:26 +0100 Subject: [PATCH 02/14] feat(pyprql/magic): adds ipython magic This is a minimal working example. It will fail in many cases, namely when used as a line magic where arguments are passed. --- pyprql/magic/__init__.py | 7 ++++ pyprql/magic/prql.py | 69 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 pyprql/magic/__init__.py create mode 100644 pyprql/magic/prql.py diff --git a/pyprql/magic/__init__.py b/pyprql/magic/__init__.py new file mode 100644 index 0000000..fe32625 --- /dev/null +++ b/pyprql/magic/__init__.py @@ -0,0 +1,7 @@ +# -*- coding: utf-8 -*- +"""PRQL magic wrapping ipython-sql.""" +from IPython import get_ipython + +from .prql import PRQLMagic + +get_ipython().register_magics(PRQLMagic) diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py new file mode 100644 index 0000000..92e8d48 --- /dev/null +++ b/pyprql/magic/prql.py @@ -0,0 +1,69 @@ +# -*- coding: utf-8 -*- +"""A magic class for parsing PRQL in IPython or Jupyter.""" +from typing import Any, Dict + +from IPython import InteractiveShell +from IPython.core.magic import cell_magic, line_magic, magics_class, needs_local_scope +from prql_python import to_sql +from sql.magic import SqlMagic + + +@magics_class +class PRQLMagic(SqlMagic): + """Perform PRQL magics. + + This is a thin wrapper around ``sql.SqlMagic``, + the class that provides the ``%%sql`` magic. + For full documentation on usage and features, + please see their docs_. + + .. _docs: https://github.com/catherinedevlin/ipython-sql + + Parameters + ---------- + shell : InteractiveShell + The current IPython shell instance. + Since instantiation is handled by IPython, + the user should never need to create this clas manually. + """ + + def __init__(self, shell: InteractiveShell): + super().__init__(shell) + + @needs_local_scope + @line_magic + @cell_magic + def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: + """Create the PRQL magic. + + If used as a line magic, + then the line is assumed to be PRQL and parsed to SQL. + If used as a cell magic, + then the line is passed untouched, + but the cell contents are parsed to SQL. + Then, + the parameters are passed to ``sql.SqlMagic.execute``. + + Parameters + ---------- + line : str + The magic's line contents. + cell : str + The magic's cell contents. + local_ns : Dict + The variables local to the running IPython shell. + + Returns + ------- + Any + Depending on the arguments passed, + this could be one of several items, + such as a ``sqlalchemy`` connection or a ``pandas`` dataframe. + """ + if line != "": + # Assume line magic doesn't take arguments + line = to_sql(line) + if cell != "": + # If a cell magic, always convert to prql + cell = to_sql(cell) + super().execute(line=line, cell=cell, local_ns=local_ns) From df4a218ab0a7460fd3e5bf4e10fef9777a810a7d Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Mon, 16 May 2022 10:31:55 +0100 Subject: [PATCH 03/14] feat(magic/prql.py): rough working functionality Major changes still required. Currently assumes that line magic will only be used to set up connection strings and options. Additionally, cell magic only returns correct results if the results are passed to a local variable. --- poetry.lock | 6 +++--- pyproject.toml | 2 +- pyprql/magic/prql.py | 14 ++------------ 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7ce011e..cf2b541 100644 --- a/poetry.lock +++ b/poetry.lock @@ -835,7 +835,7 @@ python-versions = "*" [[package]] name = "pre-commit" -version = "2.18.1" +version = "2.19.0" description = "A framework for managing and maintaining multi-language pre-commit hooks." category = "dev" optional = false @@ -1980,8 +1980,8 @@ pprintpp = [ {file = "pprintpp-0.4.0.tar.gz", hash = "sha256:ea826108e2c7f49dc6d66c752973c3fc9749142a798d6b254e1e301cfdbc6403"}, ] pre-commit = [ - {file = "pre_commit-2.18.1-py2.py3-none-any.whl", hash = "sha256:02226e69564ebca1a070bd1f046af866aa1c318dbc430027c50ab832ed2b73f2"}, - {file = "pre_commit-2.18.1.tar.gz", hash = "sha256:5d445ee1fa8738d506881c5d84f83c62bb5be6b2838e32207433647e8e5ebe10"}, + {file = "pre_commit-2.19.0-py2.py3-none-any.whl", hash = "sha256:10c62741aa5704faea2ad69cb550ca78082efe5697d6f04e5710c3c229afdd10"}, + {file = "pre_commit-2.19.0.tar.gz", hash = "sha256:4233a1e38621c87d9dda9808c6606d7e7ba0e087cd56d3fe03202a01d2919615"}, ] prettytable = [ {file = "prettytable-0.7.2.tar.bz2", hash = "sha256:853c116513625c738dc3ce1aee148b5b5757a86727e67eff6502c7ca59d43c36"}, diff --git a/pyproject.toml b/pyproject.toml index eee487f..8e702f4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,8 +36,8 @@ numpy = [ {version = "^1.22.3", python = "^3.8"} ] prql-python = "^0" -ipython-sql = "^0.4.0" ipython = "7.33.0" +ipython-sql = "^0.4.0" [tool.poetry.dev-dependencies] pytest = "^7.0.1" diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py index 92e8d48..26f1074 100644 --- a/pyprql/magic/prql.py +++ b/pyprql/magic/prql.py @@ -36,14 +36,6 @@ def __init__(self, shell: InteractiveShell): def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: """Create the PRQL magic. - If used as a line magic, - then the line is assumed to be PRQL and parsed to SQL. - If used as a cell magic, - then the line is passed untouched, - but the cell contents are parsed to SQL. - Then, - the parameters are passed to ``sql.SqlMagic.execute``. - Parameters ---------- line : str @@ -60,10 +52,8 @@ def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: this could be one of several items, such as a ``sqlalchemy`` connection or a ``pandas`` dataframe. """ - if line != "": - # Assume line magic doesn't take arguments - line = to_sql(line) + # Assume line will only take arguments + # So cell will always need to be parsed if cell != "": - # If a cell magic, always convert to prql cell = to_sql(cell) super().execute(line=line, cell=cell, local_ns=local_ns) From e21d4b9364c69ccedbbe6482fcb455ba6f10f979 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Mon, 16 May 2022 10:54:57 +0100 Subject: [PATCH 04/14] feat(pyproject.toml): add duckdb-engine Allows magic to use duckdb connection strings. --- poetry.lock | 69 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 1 + 2 files changed, 69 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index cf2b541..b08bcfc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -268,6 +268,29 @@ toml = "*" [package.extras] pipenv = ["pipenv"] +[[package]] +name = "duckdb" +version = "0.3.4" +description = "DuckDB embedded database" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +numpy = ">=1.14" + +[[package]] +name = "duckdb-engine" +version = "0.1.8" +description = "" +category = "main" +optional = false +python-versions = ">=3.6.1" + +[package.dependencies] +duckdb = ">=0.2.8" +sqlalchemy = ">=1.3.19,<2.0.0" + [[package]] name = "execnet" version = "1.9.0" @@ -1445,7 +1468,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7.1" -content-hash = "f6bbadeb4b9adf2c027c5c2c152a22ed58080728475f1de43dd3ad3e7edb53d9" +content-hash = "8e26fafb5fb19dfb1d38e6a7f559db79c06b2022594b1737b99b5caefea911d2" [metadata.files] alabaster = [ @@ -1604,6 +1627,50 @@ dparse = [ {file = "dparse-0.5.1-py3-none-any.whl", hash = "sha256:e953a25e44ebb60a5c6efc2add4420c177f1d8404509da88da9729202f306994"}, {file = "dparse-0.5.1.tar.gz", hash = "sha256:a1b5f169102e1c894f9a7d5ccf6f9402a836a5d24be80a986c7ce9eaed78f367"}, ] +duckdb = [ + {file = "duckdb-0.3.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4ecfa5e8c6bde61efead473b05b35ed989dc08fe76c7ab1c931e4c16e082b10b"}, + {file = "duckdb-0.3.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7bda539e070d08391b36370e847122350c66d90d9fdf20727b23cde86847fa39"}, + {file = "duckdb-0.3.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d913ea8d59c4004508ed2a21b70dcf7c5cd5d667e7a48efac01e0453627aadc"}, + {file = "duckdb-0.3.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eeab0867e5194e14ea39dbe1d14164c058c9d9fff1328b120361fa6da87aa622"}, + {file = "duckdb-0.3.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0695ee38ad8b2fa4390507ef75c491c93bb508dbe636fec4d08f66bc20b2f911"}, + {file = "duckdb-0.3.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:b4a743dc8f1e78539070295be548dfbb7a01c1625d2e37f2414068378a11c3d5"}, + {file = "duckdb-0.3.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6202a9f611aa6526db9699ba625ee0518ca3e269642d6955b995375285f38a7e"}, + {file = "duckdb-0.3.4-cp310-cp310-win32.whl", hash = "sha256:f3452e6780756508f07cd45b696dd92a08adac02d032442ffb4146578c31ff19"}, + {file = "duckdb-0.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:e27f5a6e486785797afc109204dffc81982e6eb0af2001e1e1709dd25c0c203d"}, + {file = "duckdb-0.3.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6e0b88fd0a905e23efb5555f22b980952494c9b94f103c14ea3b613019522095"}, + {file = "duckdb-0.3.4-cp36-cp36m-win32.whl", hash = "sha256:99ba0cdfbbaee22828cb936c4c324617476970359ff6a9e80b5b7daf4269c500"}, + {file = "duckdb-0.3.4-cp36-cp36m-win_amd64.whl", hash = "sha256:03020e992d6093a68ab597e11da2e34587863f238bcc317690e1fec1e93bca41"}, + {file = "duckdb-0.3.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d6280debb6c10a44b1efa073ba07fb067911f3e11d7f5ae9db715478a819a67d"}, + {file = "duckdb-0.3.4-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b2107da403605bf68692ed5b9194e5692290bd73fa9abdd48fde82be0d6457d"}, + {file = "duckdb-0.3.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e47ab2f2112a258f2e8fae66321009bb51253d674fadf7dd964be0886514684c"}, + {file = "duckdb-0.3.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9df6867017644f016cde47da37de57065540d3cfa410e50b943bd90f42d96110"}, + {file = "duckdb-0.3.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0da2cadcdfbf9aa2e34eba9cc4413ed7c635aaa0bb4cafef7eb37d951f205223"}, + {file = "duckdb-0.3.4-cp37-cp37m-win32.whl", hash = "sha256:672645773abbe32801bf543d12a1189dbc67122db4da6b90a57f3acecd525dbf"}, + {file = "duckdb-0.3.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6fa14f1d3cf225f788ad7f055e25b98d99c06d3a379df4b788fdf66ebe7f9b98"}, + {file = "duckdb-0.3.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:155f6717ad9fe1aa99d8d631508d2577b06519661b7e30cb14cff46a0446558c"}, + {file = "duckdb-0.3.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:013a65ddac424d2d778dff37d5b1e91c2f68365436cc8ec76ea45a906313e0bf"}, + {file = "duckdb-0.3.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba1d627a913154c651daca5ca168b8fa49caa6792a61f069f30eae645a8d52cd"}, + {file = "duckdb-0.3.4-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8d4e960945955b19ba051e5bb0d6b17c3bcea3d29f9114bb94faaa7585df8c5"}, + {file = "duckdb-0.3.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56ecd82eb31d89ff349059fd909e02906efa1971faeec1a0f7a81357d09d1ad9"}, + {file = "duckdb-0.3.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:78c8d2c6629e14140fd038402bf3cbb8c2017ba68148c29c66f8142ffa8f3a39"}, + {file = "duckdb-0.3.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4811c3fd101d1561d46b5d6c7b9915c3b2adbc8a6270e7cddc63411c6a4b4a0c"}, + {file = "duckdb-0.3.4-cp38-cp38-win32.whl", hash = "sha256:aa42d850cf2dd3f5f664f7a9c8be548f8618064ca6260808fa4e361a334ce2b1"}, + {file = "duckdb-0.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:6ec0be5153a35e3a7462c014a90bba81964f63f114af3f25384b97b0bf5fcae7"}, + {file = "duckdb-0.3.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e35d92606c34cfb56f084eca2540db6573b260f974245465f6dae9dbcdbe6434"}, + {file = "duckdb-0.3.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54cf2d11ea8e8a9d474a83137ea654a66b2ac7ea26f615ef4498b9e3fb5091f1"}, + {file = "duckdb-0.3.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:de8762917c1349c1517487500d5975c2788f3544b82ae341d79984eaa836e20a"}, + {file = "duckdb-0.3.4-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60a163e65a1afdf410b2b9cbecd124875a53e53ad9271bdd66ed98ae42034778"}, + {file = "duckdb-0.3.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f552592ac977d368ea02c6a89b62373fb53a49a36aa8e7d3b3c89999ee420010"}, + {file = "duckdb-0.3.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a1c355929e06f22f35a2d3a74c16721d7b2ecd35e5088bf9722f1ca574ff5a2b"}, + {file = "duckdb-0.3.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f5c65d6a4afa8c313c612d6bc92bca055f1cbcc81646640d5dde797c745b7876"}, + {file = "duckdb-0.3.4-cp39-cp39-win32.whl", hash = "sha256:79256b5521c3945f540dd4ccfcc7658d18e98a42ba619c5571eb075fc234b5a1"}, + {file = "duckdb-0.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:f38cdf5a55a4a4f18c30d2ad73055d4531679fa3282cb08cacf2646f0a0150be"}, + {file = "duckdb-0.3.4.tar.gz", hash = "sha256:ab94cfc9e4c25f93d4a7be2063879475c308d771d53588bfd6198a89a8c2bcd2"}, +] +duckdb-engine = [ + {file = "duckdb_engine-0.1.8-py3-none-any.whl", hash = "sha256:308c1318b1b526a5d89be2c7b3da748a4189aae4916151fd3ade65611377fbec"}, + {file = "duckdb_engine-0.1.8.tar.gz", hash = "sha256:08688e92e0c872e498f4f7bddec252fc0368bbc5b67028fab608ffdcd3d9197a"}, +] execnet = [ {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, diff --git a/pyproject.toml b/pyproject.toml index 8e702f4..11f3e77 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,6 +38,7 @@ numpy = [ prql-python = "^0" ipython = "7.33.0" ipython-sql = "^0.4.0" +duckdb-engine = "^0.1.8" [tool.poetry.dev-dependencies] pytest = "^7.0.1" From f3a5274e5e72ce750bf60b7ea21d97b862a3fe45 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Mon, 16 May 2022 11:14:49 +0100 Subject: [PATCH 05/14] fix(magic/prql.py): change default configurations Defaults autopandas to true and displayconn to false. --- poetry.lock | 10 +++++----- pyproject.toml | 1 + pyprql/magic/prql.py | 8 ++++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index b08bcfc..fd0e739 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1370,14 +1370,14 @@ python-versions = ">=3.6,<4.0" [[package]] name = "traitlets" -version = "5.1.1" +version = "5.2.0" description = "Traitlets Python configuration system" category = "main" optional = false python-versions = ">=3.7" [package.extras] -test = ["pytest"] +test = ["pytest", "pre-commit"] [[package]] name = "typed-ast" @@ -1468,7 +1468,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7.1" -content-hash = "8e26fafb5fb19dfb1d38e6a7f559db79c06b2022594b1737b99b5caefea911d2" +content-hash = "194ef71e7e966207deab779aa98ea21475e65ae6d3e3fdf3d9fe0ce9600b4efe" [metadata.files] alabaster = [ @@ -2276,8 +2276,8 @@ tomlkit = [ {file = "tomlkit-0.10.2.tar.gz", hash = "sha256:30d54c0b914e595f3d10a87888599eab5321a2a69abc773bbefff51599b72db6"}, ] traitlets = [ - {file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"}, - {file = "traitlets-5.1.1.tar.gz", hash = "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7"}, + {file = "traitlets-5.2.0-py3-none-any.whl", hash = "sha256:9dd4025123fbe018a2092b2ad6984792f53ea3362c698f37473258b1fa97b0bc"}, + {file = "traitlets-5.2.0.tar.gz", hash = "sha256:60474f39bf1d39a11e0233090b99af3acee93bbc2281777e61dd8c87da8a0014"}, ] typed-ast = [ {file = "typed_ast-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ad3b48cf2b487be140072fb86feff36801487d4abb7382bb1929aaac80638ea"}, diff --git a/pyproject.toml b/pyproject.toml index 11f3e77..90796c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ prql-python = "^0" ipython = "7.33.0" ipython-sql = "^0.4.0" duckdb-engine = "^0.1.8" +traitlets = "^5.2.0" [tool.poetry.dev-dependencies] pytest = "^7.0.1" diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py index 26f1074..7240470 100644 --- a/pyprql/magic/prql.py +++ b/pyprql/magic/prql.py @@ -6,6 +6,7 @@ from IPython.core.magic import cell_magic, line_magic, magics_class, needs_local_scope from prql_python import to_sql from sql.magic import SqlMagic +from traitlets import Bool @magics_class @@ -27,6 +28,13 @@ class PRQLMagic(SqlMagic): the user should never need to create this clas manually. """ + displaycon = Bool(False, config=True, help="Show connection string after execute") + autopandas = Bool( + True, + config=True, + help="Return Pandas DataFrames instead of regular result sets", + ) + def __init__(self, shell: InteractiveShell): super().__init__(shell) From a53e172962fa9db31db879f486b436732d07c854 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Mon, 16 May 2022 16:25:41 +0100 Subject: [PATCH 06/14] fix(magic/prql.py): fix printing of results By providing an autoview parameter and manually specifying `_` as the return variable, we can ensure that results are always accessible and always printable. --- pyprql/magic/prql.py | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py index 7240470..d74df89 100644 --- a/pyprql/magic/prql.py +++ b/pyprql/magic/prql.py @@ -18,6 +18,16 @@ class PRQLMagic(SqlMagic): For full documentation on usage and features, please see their docs_. + We override their defaults in two cases: + + 1. autopandas is set to ``True``. + 1. displaycon is set to ``False``. + + Additionally, + to working around some quirky behaviour, + we also provide an ``autoview`` option to indicate + whether results should be printed to the window. + .. _docs: https://github.com/catherinedevlin/ipython-sql Parameters @@ -34,6 +44,7 @@ class PRQLMagic(SqlMagic): config=True, help="Return Pandas DataFrames instead of regular result sets", ) + autoview = Bool(True, config=True, help="Display results") def __init__(self, shell: InteractiveShell): super().__init__(shell) @@ -44,6 +55,16 @@ def __init__(self, shell: InteractiveShell): def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: """Create the PRQL magic. + To handle parsing to PRQL, + there is one limitation relative to the original_ ``%%sql`` magic. + Namely, + line magics can only be used to pass connection strings and arguments. + To figure out whether the ``line`` argument contained PRQL or not + required heavy parsing followed by recosntruction of the input to pass + on to the ``%sql`` magic we are wrapping. + + .. _original: https://github.com/catherinedevlin/ipython-sql + Parameters ---------- line : str @@ -60,8 +81,22 @@ def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: this could be one of several items, such as a ``sqlalchemy`` connection or a ``pandas`` dataframe. """ - # Assume line will only take arguments - # So cell will always need to be parsed + # If cell is occupied, it must be parsed to SQL if cell != "": cell = to_sql(cell) + + # If cell is occupied and line is empty, + # we artificially populate line to ensure a return value. + if cell != "" and line == "": + line = "_ <<" + super().execute(line=line, cell=cell, local_ns=local_ns) + + # If results should be printed, + # check line for the results name. + # Default to `_`. + if self.autoview: + if "<<" in line: + print(local_ns[line.split()[0]]) + else: + print(local_ns["_"]) From 2f51f9252be0e11a8d714f3906b0f920dd93da76 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Wed, 18 May 2022 15:56:12 +0100 Subject: [PATCH 07/14] docs(*): document magic Provides full Sphinx documentation for IPython/Jupyter Magic. --- docs/cli.md | 2 +- docs/conf.py | 1 + docs/index.md | 1 + docs/magic.md | 15 ++++ docs/magic_implement.md | 7 ++ docs/magic_init.md | 7 ++ docs/magic_readme.md | 2 + docs/pyprql.md | 9 +- docs/requirements.txt | 22 +++-- poetry.lock | 124 +++++++++++++------------- pyprql/magic/README.md | 184 +++++++++++++++++++++++++++++++++++++++ pyprql/magic/__init__.py | 30 ++++++- pyprql/magic/prql.py | 10 +-- 13 files changed, 330 insertions(+), 84 deletions(-) create mode 100644 docs/magic.md create mode 100644 docs/magic_implement.md create mode 100644 docs/magic_init.md create mode 100644 docs/magic_readme.md create mode 100644 pyprql/magic/README.md diff --git a/docs/cli.md b/docs/cli.md index 7e02b88..e31d564 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -1,4 +1,4 @@ -# The Command Line Interface +# Command Line Interface In addition to providing the main entrypoint, documented below, diff --git a/docs/conf.py b/docs/conf.py index 0e6bd42..3111903 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -32,4 +32,5 @@ myst_heading_anchors = 2 myst_enable_extensions = [ "html_admonition", + "colon_fence", ] diff --git a/docs/index.md b/docs/index.md index 24f4469..7ff5bcf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,6 +23,7 @@ we'd kindly ask you to abide by our [code of conduct](./coc.md). If you'd like to learn more about the project, please see the [README](./readme.md). For information about the source code, +including the CLI and IPython/Jupyter Magic, please see the [documentation](./pyprql.md). If testing is your passion, take a peek at [testing](./tests.md). diff --git a/docs/magic.md b/docs/magic.md new file mode 100644 index 0000000..9fc546e --- /dev/null +++ b/docs/magic.md @@ -0,0 +1,15 @@ +# IPython and Jupyter Magic + +For a "how-to" and usage instructions, +please see our [magic README](./magic_readme.md). +Documentation on extension loading [lives here](./magic_init.md), +while documentation on the magic class implementation [lives here](./magic_implement.md). + +```{toctree} +:hidden: +:maxdepth: 3 + +magic_readme +magic_init +magic_implement +``` diff --git a/docs/magic_implement.md b/docs/magic_implement.md new file mode 100644 index 0000000..fa5cb53 --- /dev/null +++ b/docs/magic_implement.md @@ -0,0 +1,7 @@ +# The PyPRQL Magic Implementation + +```{eval-rst} +.. automodule:: pyprql.magic.prql + :members: + :private-members: +``` diff --git a/docs/magic_init.md b/docs/magic_init.md new file mode 100644 index 0000000..3f8d002 --- /dev/null +++ b/docs/magic_init.md @@ -0,0 +1,7 @@ +# Loading PyPRQL Magic + +```{eval-rst} +.. automodule:: pyprql.magic + :members: + :private-members: +``` diff --git a/docs/magic_readme.md b/docs/magic_readme.md new file mode 100644 index 0000000..84d3515 --- /dev/null +++ b/docs/magic_readme.md @@ -0,0 +1,2 @@ +```{include} ../pyprql/magic/README.md +``` diff --git a/docs/pyprql.md b/docs/pyprql.md index c2a1494..b0dc8f8 100644 --- a/docs/pyprql.md +++ b/docs/pyprql.md @@ -1,14 +1,19 @@ +# Source Code + Currently, the source code is divided as follows: - `cli` module contains the command line interface logic. - See [cli](./cli.md). + See [Command Line Interface](./cli.md). +- `magic` module that implements the PRQL IPython/Jupyer magic. + See [IPython and Jupyter Magic](./magic.md). - `assets` sub-package that contains a number of useful references. - See [assets](./assets.md). + See [Assets](./assets.md). ```{toctree} :hidden: :maxdepth: 3 cli +magic assets ``` diff --git a/docs/requirements.txt b/docs/requirements.txt index d8d4b87..45c8f57 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,14 +1,18 @@ -icecream==2.1.1 -rich==12.2.0 -click==8.1.2 -prompt-toolkit==3.0.2 -Pygments==2.11.2 +icecream==2.1.2 +rich==12.4.1 +click==8.1.3 +prompt-toolkit==3.0.29 +Pygments==2.12.0 fuzzyfinder==2.1.0 -SQLAlchemy==1.4.35 +SQLAlchemy==1.4.36 pandas==1.4.2 numpy==1.22.3 +prql_python==0.0.2 +ipython==7.33.0 +ipython-sql==0.4.0 +duckdb-engine==0.1.8 +traitlets==5.2.1.post0 sphinx==4.3.2 sphinx-rtd-theme==1.0.0 -myst-parser==0.17.0 -pytest==7.1.1 -prql_python==0.0.2 +myst-parser==0.17.2 +pytest==7.1.2 diff --git a/poetry.lock b/poetry.lock index fd0e739..dfac7a2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -169,7 +169,7 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"] [[package]] name = "commitizen" -version = "2.24.0" +version = "2.26.0" description = "Python commitizen client tool" category = "dev" optional = false @@ -200,7 +200,7 @@ test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] [[package]] name = "coverage" -version = "6.3.2" +version = "6.3.3" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -312,7 +312,7 @@ python-versions = "*" [[package]] name = "filelock" -version = "3.6.0" +version = "3.7.0" description = "A platform independent file lock." category = "dev" optional = false @@ -956,7 +956,7 @@ python-versions = ">=3.6" [[package]] name = "pyparsing" -version = "3.0.8" +version = "3.0.9" description = "pyparsing module - Classes and methods to define and execute parsing grammars" category = "dev" optional = false @@ -1119,7 +1119,7 @@ use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] [[package]] name = "rich" -version = "12.3.0" +version = "12.4.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" category = "main" optional = false @@ -1150,7 +1150,7 @@ setuptools = "*" [[package]] name = "setuptools" -version = "62.1.0" +version = "62.2.0" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "main" optional = false @@ -1370,14 +1370,14 @@ python-versions = ">=3.6,<4.0" [[package]] name = "traitlets" -version = "5.2.0" -description = "Traitlets Python configuration system" +version = "5.2.1.post0" +description = "" category = "main" optional = false python-versions = ">=3.7" [package.extras] -test = ["pytest", "pre-commit"] +test = ["pre-commit", "pytest"] [[package]] name = "typed-ast" @@ -1553,55 +1553,55 @@ colorlog = [ {file = "colorlog-6.6.0.tar.gz", hash = "sha256:344f73204009e4c83c5b6beb00b3c45dc70fcdae3c80db919e0a4171d006fde8"}, ] commitizen = [ - {file = "commitizen-2.24.0-py3-none-any.whl", hash = "sha256:08901b176eac6a224761d613b58fb8b19bc7d00a49282a4d4bc39e3bdb3afb50"}, - {file = "commitizen-2.24.0.tar.gz", hash = "sha256:c867c26a394b255a93a8a225dae793dd361b25160be39015d2aa75d730728295"}, + {file = "commitizen-2.26.0-py3-none-any.whl", hash = "sha256:408fdc9527b3570425fb7e7a67d5e2e4269d7533d7ff91a88c63a382a8ae85c6"}, + {file = "commitizen-2.26.0.tar.gz", hash = "sha256:a999051d5a3b2e9cce86d01ef2ad05232e827fa256cab89658dded46bcf94081"}, ] commonmark = [ {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, ] coverage = [ - {file = "coverage-6.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9b27d894748475fa858f9597c0ee1d4829f44683f3813633aaf94b19cb5453cf"}, - {file = "coverage-6.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37d1141ad6b2466a7b53a22e08fe76994c2d35a5b6b469590424a9953155afac"}, - {file = "coverage-6.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9987b0354b06d4df0f4d3e0ec1ae76d7ce7cbca9a2f98c25041eb79eec766f1"}, - {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:26e2deacd414fc2f97dd9f7676ee3eaecd299ca751412d89f40bc01557a6b1b4"}, - {file = "coverage-6.3.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4dd8bafa458b5c7d061540f1ee9f18025a68e2d8471b3e858a9dad47c8d41903"}, - {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:46191097ebc381fbf89bdce207a6c107ac4ec0890d8d20f3360345ff5976155c"}, - {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6f89d05e028d274ce4fa1a86887b071ae1755082ef94a6740238cd7a8178804f"}, - {file = "coverage-6.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:58303469e9a272b4abdb9e302a780072c0633cdcc0165db7eec0f9e32f901e05"}, - {file = "coverage-6.3.2-cp310-cp310-win32.whl", hash = "sha256:2fea046bfb455510e05be95e879f0e768d45c10c11509e20e06d8fcaa31d9e39"}, - {file = "coverage-6.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:a2a8b8bcc399edb4347a5ca8b9b87e7524c0967b335fbb08a83c8421489ddee1"}, - {file = "coverage-6.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f1555ea6d6da108e1999b2463ea1003fe03f29213e459145e70edbaf3e004aaa"}, - {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5f4e1edcf57ce94e5475fe09e5afa3e3145081318e5fd1a43a6b4539a97e518"}, - {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a15dc0a14008f1da3d1ebd44bdda3e357dbabdf5a0b5034d38fcde0b5c234b7"}, - {file = "coverage-6.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21b7745788866028adeb1e0eca3bf1101109e2dc58456cb49d2d9b99a8c516e6"}, - {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8ce257cac556cb03be4a248d92ed36904a59a4a5ff55a994e92214cde15c5bad"}, - {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b0be84e5a6209858a1d3e8d1806c46214e867ce1b0fd32e4ea03f4bd8b2e3359"}, - {file = "coverage-6.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:acf53bc2cf7282ab9b8ba346746afe703474004d9e566ad164c91a7a59f188a4"}, - {file = "coverage-6.3.2-cp37-cp37m-win32.whl", hash = "sha256:8bdde1177f2311ee552f47ae6e5aa7750c0e3291ca6b75f71f7ffe1f1dab3dca"}, - {file = "coverage-6.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b31651d018b23ec463e95cf10070d0b2c548aa950a03d0b559eaa11c7e5a6fa3"}, - {file = "coverage-6.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07e6db90cd9686c767dcc593dff16c8c09f9814f5e9c51034066cad3373b914d"}, - {file = "coverage-6.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c6dbb42f3ad25760010c45191e9757e7dce981cbfb90e42feef301d71540059"}, - {file = "coverage-6.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c76aeef1b95aff3905fb2ae2d96e319caca5b76fa41d3470b19d4e4a3a313512"}, - {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cf5cfcb1521dc3255d845d9dca3ff204b3229401994ef8d1984b32746bb45ca"}, - {file = "coverage-6.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fbbdc8d55990eac1b0919ca69eb5a988a802b854488c34b8f37f3e2025fa90d"}, - {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ec6bc7fe73a938933d4178c9b23c4e0568e43e220aef9472c4f6044bfc6dd0f0"}, - {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9baff2a45ae1f17c8078452e9e5962e518eab705e50a0aa8083733ea7d45f3a6"}, - {file = "coverage-6.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd9e830e9d8d89b20ab1e5af09b32d33e1a08ef4c4e14411e559556fd788e6b2"}, - {file = "coverage-6.3.2-cp38-cp38-win32.whl", hash = "sha256:f7331dbf301b7289013175087636bbaf5b2405e57259dd2c42fdcc9fcc47325e"}, - {file = "coverage-6.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:68353fe7cdf91f109fc7d474461b46e7f1f14e533e911a2a2cbb8b0fc8613cf1"}, - {file = "coverage-6.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b78e5afb39941572209f71866aa0b206c12f0109835aa0d601e41552f9b3e620"}, - {file = "coverage-6.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4e21876082ed887baed0146fe222f861b5815455ada3b33b890f4105d806128d"}, - {file = "coverage-6.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34626a7eee2a3da12af0507780bb51eb52dca0e1751fd1471d0810539cefb536"}, - {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ebf730d2381158ecf3dfd4453fbca0613e16eaa547b4170e2450c9707665ce7"}, - {file = "coverage-6.3.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd6fe30bd519694b356cbfcaca9bd5c1737cddd20778c6a581ae20dc8c04def2"}, - {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96f8a1cb43ca1422f36492bebe63312d396491a9165ed3b9231e778d43a7fca4"}, - {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:dd035edafefee4d573140a76fdc785dc38829fe5a455c4bb12bac8c20cfc3d69"}, - {file = "coverage-6.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5ca5aeb4344b30d0bec47481536b8ba1181d50dbe783b0e4ad03c95dc1296684"}, - {file = "coverage-6.3.2-cp39-cp39-win32.whl", hash = "sha256:f5fa5803f47e095d7ad8443d28b01d48c0359484fec1b9d8606d0e3282084bc4"}, - {file = "coverage-6.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:9548f10d8be799551eb3a9c74bbf2b4934ddb330e08a73320123c07f95cc2d92"}, - {file = "coverage-6.3.2-pp36.pp37.pp38-none-any.whl", hash = "sha256:18d520c6860515a771708937d2f78f63cc47ab3b80cb78e86573b0a760161faf"}, - {file = "coverage-6.3.2.tar.gz", hash = "sha256:03e2a7826086b91ef345ff18742ee9fc47a6839ccd517061ef8fa1976e652ce9"}, + {file = "coverage-6.3.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df32ee0f4935a101e4b9a5f07b617d884a531ed5666671ff6ac66d2e8e8246d8"}, + {file = "coverage-6.3.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:75b5dbffc334e0beb4f6c503fb95e6d422770fd2d1b40a64898ea26d6c02742d"}, + {file = "coverage-6.3.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:114944e6061b68a801c5da5427b9173a0dd9d32cd5fcc18a13de90352843737d"}, + {file = "coverage-6.3.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ab88a01cd180b5640ccc9c47232e31924d5f9967ab7edd7e5c91c68eee47a69"}, + {file = "coverage-6.3.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad8f9068f5972a46d50fe5f32c09d6ee11da69c560fcb1b4c3baea246ca4109b"}, + {file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4cd696aa712e6cd16898d63cf66139dc70d998f8121ab558f0e1936396dbc579"}, + {file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c1a9942e282cc9d3ed522cd3e3cab081149b27ea3bda72d6f61f84eaf88c1a63"}, + {file = "coverage-6.3.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c06455121a089252b5943ea682187a4e0a5cf0a3fb980eb8e7ce394b144430a9"}, + {file = "coverage-6.3.3-cp310-cp310-win32.whl", hash = "sha256:cb5311d6ccbd22578c80028c5e292a7ab9adb91bd62c1982087fad75abe2e63d"}, + {file = "coverage-6.3.3-cp310-cp310-win_amd64.whl", hash = "sha256:6d4a6f30f611e657495cc81a07ff7aa8cd949144e7667c5d3e680d73ba7a70e4"}, + {file = "coverage-6.3.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:79bf405432428e989cad7b8bc60581963238f7645ae8a404f5dce90236cc0293"}, + {file = "coverage-6.3.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:338c417613f15596af9eb7a39353b60abec9d8ce1080aedba5ecee6a5d85f8d3"}, + {file = "coverage-6.3.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db094a6a4ae6329ed322a8973f83630b12715654c197dd392410400a5bfa1a73"}, + {file = "coverage-6.3.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1414e8b124611bf4df8d77215bd32cba6e3425da8ce9c1f1046149615e3a9a31"}, + {file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:93b16b08f94c92cab88073ffd185070cdcb29f1b98df8b28e6649145b7f2c90d"}, + {file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fbc86ae8cc129c801e7baaafe3addf3c8d49c9c1597c44bdf2d78139707c3c62"}, + {file = "coverage-6.3.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b5ba058610e8289a07db2a57bce45a1793ec0d3d11db28c047aae2aa1a832572"}, + {file = "coverage-6.3.3-cp37-cp37m-win32.whl", hash = "sha256:8329635c0781927a2c6ae068461e19674c564e05b86736ab8eb29c420ee7dc20"}, + {file = "coverage-6.3.3-cp37-cp37m-win_amd64.whl", hash = "sha256:e5af1feee71099ae2e3b086ec04f57f9950e1be9ecf6c420696fea7977b84738"}, + {file = "coverage-6.3.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e814a4a5a1d95223b08cdb0f4f57029e8eab22ffdbae2f97107aeef28554517e"}, + {file = "coverage-6.3.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:61f4fbf3633cb0713437291b8848634ea97f89c7e849c2be17a665611e433f53"}, + {file = "coverage-6.3.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3401b0d2ed9f726fadbfa35102e00d1b3547b73772a1de5508ef3bdbcb36afe7"}, + {file = "coverage-6.3.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8586b177b4407f988731eb7f41967415b2197f35e2a6ee1a9b9b561f6323c8e9"}, + {file = "coverage-6.3.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:892e7fe32191960da559a14536768a62e83e87bbb867e1b9c643e7e0fbce2579"}, + {file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:afb03f981fadb5aed1ac6e3dd34f0488e1a0875623d557b6fad09b97a942b38a"}, + {file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cbe91bc84be4e5ef0b1480d15c7b18e29c73bdfa33e07d3725da7d18e1b0aff2"}, + {file = "coverage-6.3.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:91502bf27cbd5c83c95cfea291ef387469f2387508645602e1ca0fd8a4ba7548"}, + {file = "coverage-6.3.3-cp38-cp38-win32.whl", hash = "sha256:c488db059848702aff30aa1d90ef87928d4e72e4f00717343800546fdbff0a94"}, + {file = "coverage-6.3.3-cp38-cp38-win_amd64.whl", hash = "sha256:ceb6534fcdfb5c503affb6b1130db7b5bfc8a0f77fa34880146f7a5c117987d0"}, + {file = "coverage-6.3.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cc692c9ee18f0dd3214843779ba6b275ee4bb9b9a5745ba64265bce911aefd1a"}, + {file = "coverage-6.3.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:462105283de203df8de58a68c1bb4ba2a8a164097c2379f664fa81d6baf94b81"}, + {file = "coverage-6.3.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc972d829ad5ef4d4c5fcabd2bbe2add84ce8236f64ba1c0c72185da3a273130"}, + {file = "coverage-6.3.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:06f54765cdbce99901871d50fe9f41d58213f18e98b170a30ca34f47de7dd5e8"}, + {file = "coverage-6.3.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7835f76a081787f0ca62a53504361b3869840a1620049b56d803a8cb3a9eeea3"}, + {file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6f5fee77ec3384b934797f1873758f796dfb4f167e1296dc00f8b2e023ce6ee9"}, + {file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:baa8be8aba3dd1e976e68677be68a960a633a6d44c325757aefaa4d66175050f"}, + {file = "coverage-6.3.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4d06380e777dd6b35ee936f333d55b53dc4a8271036ff884c909cf6e94be8b6c"}, + {file = "coverage-6.3.3-cp39-cp39-win32.whl", hash = "sha256:f8cabc5fd0091976ab7b020f5708335033e422de25e20ddf9416bdce2b7e07d8"}, + {file = "coverage-6.3.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c9441d57b0963cf8340268ad62fc83de61f1613034b79c2b1053046af0c5284"}, + {file = "coverage-6.3.3-pp36.pp37.pp38-none-any.whl", hash = "sha256:d522f1dc49127eab0bfbba4e90fa068ecff0899bbf61bf4065c790ddd6c177fe"}, + {file = "coverage-6.3.3.tar.gz", hash = "sha256:2781c43bffbbec2b8867376d4d61916f5e9c4cc168232528562a61d1b4b01879"}, ] darglint = [ {file = "darglint-1.8.1-py3-none-any.whl", hash = "sha256:5ae11c259c17b0701618a20c3da343a3eb98b3bc4b5a83d31cdd94f5ebdced8d"}, @@ -1680,8 +1680,8 @@ executing = [ {file = "executing-0.8.3.tar.gz", hash = "sha256:c6554e21c6b060590a6d3be4b82fb78f8f0194d809de5ea7df1c093763311501"}, ] filelock = [ - {file = "filelock-3.6.0-py3-none-any.whl", hash = "sha256:f8314284bfffbdcfa0ff3d7992b023d4c628ced6feb957351d4c48d059f56bc0"}, - {file = "filelock-3.6.0.tar.gz", hash = "sha256:9cd540a9352e432c7246a48fe4e8712b10acb1df2ad1f30e8c070b82ae1fed85"}, + {file = "filelock-3.7.0-py3-none-any.whl", hash = "sha256:c7b5fdb219b398a5b28c8e4c1893ef5f98ece6a38c6ab2c22e26ec161556fed6"}, + {file = "filelock-3.7.0.tar.gz", hash = "sha256:b795f1b42a61bbf8ec7113c341dad679d772567b936fbd1bf43c9a238e673e20"}, ] flake8 = [ {file = "flake8-4.0.1-py2.py3-none-any.whl", hash = "sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d"}, @@ -2090,8 +2090,8 @@ pygments = [ {file = "Pygments-2.12.0.tar.gz", hash = "sha256:5eb116118f9612ff1ee89ac96437bb6b49e8f04d8a13b514ba26f620208e26eb"}, ] pyparsing = [ - {file = "pyparsing-3.0.8-py3-none-any.whl", hash = "sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06"}, - {file = "pyparsing-3.0.8.tar.gz", hash = "sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954"}, + {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, + {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pytest = [ {file = "pytest-7.1.2-py3-none-any.whl", hash = "sha256:13d0e3ccfc2b6e26be000cb6568c832ba67ba32e719443bfe725814d3c42433c"}, @@ -2167,16 +2167,16 @@ requests = [ {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, ] rich = [ - {file = "rich-12.3.0-py3-none-any.whl", hash = "sha256:0eb63013630c6ee1237e0e395d51cb23513de6b5531235e33889e8842bdf3a6f"}, - {file = "rich-12.3.0.tar.gz", hash = "sha256:7e8700cda776337036a712ff0495b04052fb5f957c7dfb8df997f88350044b64"}, + {file = "rich-12.4.1-py3-none-any.whl", hash = "sha256:d13c6c90c42e24eb7ce660db397e8c398edd58acb7f92a2a88a95572b838aaa4"}, + {file = "rich-12.4.1.tar.gz", hash = "sha256:d239001c0fb7de985e21ec9a4bb542b5150350330bbc1849f835b9cbc8923b91"}, ] safety = [ {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, ] setuptools = [ - {file = "setuptools-62.1.0-py3-none-any.whl", hash = "sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8"}, - {file = "setuptools-62.1.0.tar.gz", hash = "sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592"}, + {file = "setuptools-62.2.0-py3-none-any.whl", hash = "sha256:5534570b9980fc650d45c62877ff603c7aaaf24893371708736cc016bd221c3c"}, + {file = "setuptools-62.2.0.tar.gz", hash = "sha256:ca6ba73b7fd5f734ae70ece8c4c1f7062b07f3352f6428f6277e27c8f5c64237"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, @@ -2276,8 +2276,8 @@ tomlkit = [ {file = "tomlkit-0.10.2.tar.gz", hash = "sha256:30d54c0b914e595f3d10a87888599eab5321a2a69abc773bbefff51599b72db6"}, ] traitlets = [ - {file = "traitlets-5.2.0-py3-none-any.whl", hash = "sha256:9dd4025123fbe018a2092b2ad6984792f53ea3362c698f37473258b1fa97b0bc"}, - {file = "traitlets-5.2.0.tar.gz", hash = "sha256:60474f39bf1d39a11e0233090b99af3acee93bbc2281777e61dd8c87da8a0014"}, + {file = "traitlets-5.2.1.post0-py3-none-any.whl", hash = "sha256:f44b708d33d98b0addb40c29d148a761f44af740603a8fd0e2f8b5b27cf0f087"}, + {file = "traitlets-5.2.1.post0.tar.gz", hash = "sha256:70815ecb20ec619d1af28910ade523383be13754283aef90528eb3d47b77c5db"}, ] typed-ast = [ {file = "typed_ast-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9ad3b48cf2b487be140072fb86feff36801487d4abb7382bb1929aaac80638ea"}, diff --git a/pyprql/magic/README.md b/pyprql/magic/README.md new file mode 100644 index 0000000..c75c934 --- /dev/null +++ b/pyprql/magic/README.md @@ -0,0 +1,184 @@ +# Using the IPython and Jupyter Magic + +Work with pandas and PRQL in an IPython terminal or Jupyter notebook. + +## Implementation + +This is a this wrapper around the fantastic +[IPython-sql][ipysql] magic. +Roughly speaking, +all we do is parse PRQL to SQL and pass that through to `ipython-sql`. +A full documentation of the supported features is available at their +[repository][ipysql]. +Here, +we document those places where we differ from them, +plus those features we think you are mostly likely to find useful. + +## Usage + +### Installation + +If you have already installed PyPRQL into your environment, +then you should be could to go! +We bundle in `IPython` and `pandas`, +though you'll need to install `Jupyter` separately. +If you haven't installed PyPRQL, +that's as simple as: + +```shell +pip install PyPRQL +``` + +### Set Up + +Open up either an `IPython` terminal or `Jupyter` notebook. +First, +we need to load the extension and connect to a database. + +```python +In [1]: %load_ext pyprql.magic + +In [2]: %prql duckdb:///:memory: + +``` + +When connecting to a database, +pass the connection string as an argument to the line magic `%prql`. +The connection string needs to be in [SQLAlchemy format][conn_str], +so any connection supported by `SQLAlchemy` is supported by the magic. +Additional connection parameters can be passed as a dictionary using the `--connection_arguments` +flag to the the `%prql` line magic. +We ship with the necessary extensions to use [DuckDB][duckdb] +as the backend, +and here connect to an in-memory database. + +However, +in-memory databases start off empty! +So, +we need to add some data. +This is where [pandas][pandas] +comes into play. +We can easily add a dataframe to the `DuckDB` database like so: + +```python +In [3]: %prql --persist data + +``` + +where data is a pandas dataframe we have already loaded. +This adds a table named `data` to the in-memory `DuckDB` instance. +If you connect to an existing SQL database, +then all the tables normally there will be accessible. + +### Usage + +:::{Important} +This is one area where we differe from `IPython-sql`. +We only support parasing PRQL as a cell magic, +not as a line magic. +::: + +Now, +let's do a query! +By default, +`PRQLMagic` always returns the results as dataframe, +and always prints the results. +The results of the previous query are accessible in the `_` variable. + +```python +In [4]: %%prql +from data +filter freq > 100 +select [ food_name ] + +Done. +Returning data to local variable _ + food_name +0 Abalone +1 Savoy cabbage +2 Kiwi +3 Angelica +``` + +If you want to, +you can capture the results into a different variable like so: + +```python +In [5]: %%prql results << +from data +filter freq > 100 +select [ food_name ] + +Done. +Returning data to local variable results + food_name +0 Abalone +1 Savoy cabbage +2 Kiwi +3 Angelica +``` + +Now, +the output of the query is saved to `results`. + +## Configuration + +We strive to provide sane defaults; +however, +should you need to change settings, +a list of settings is available using the `%config` line magic. + +```python +In [6]: %config PRQLMagic +PRQLMagic(SqlMagic) options +------------------------- +PRQLMagic.autocommit= + Set autocommit mode + Current: True +PRQLMagic.autolimit= + Automatically limit the size of the returned result sets + Current: 0 +PRQLMagic.autopandas= + Return Pandas DataFrames instead of regular result sets + Current: True +PRQLMagic.autoview= + Display results + Current: True +PRQLMagic.column_local_vars= + Return data into local variables from column names + Current: False +PRQLMagic.displaycon= + Show connection string after execute + Current: False +PRQLMagic.displaylimit= + Automatically limit the number of rows displayed (full result set is still + stored) + Current: None +PRQLMagic.dsn_filename= + Path to DSN file. When the first argument is of the form [section], a + sqlalchemy connection string is formed from the matching section in the DSN + file. + Current: 'odbc.ini' +PRQLMagic.feedback= + Print number of rows affected by DML + Current: True +PRQLMagic.short_errors= + Don't display the full traceback on SQL Programming Error + Current: True +PRQLMagic.style= + Set the table printing style to any of prettytable's defined styles + (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM) + Current: 'DEFAULT' +``` + +If you want to change any of these, +you can do that with the `%config` line magic as well. + +```python +In [7]: %config PRQLMagic.autoview = False +``` + +[ipysql]: https://github.com/catherinedevlin/ipython-sql +[conn_str]: https://docs.sqlalchemy.org/en/14/core/engines.html#database-urls +[duckdb]: https://duckdb.org +[pandas]: https://pandas.pydata.org diff --git a/pyprql/magic/__init__.py b/pyprql/magic/__init__.py index fe32625..e742d55 100644 --- a/pyprql/magic/__init__.py +++ b/pyprql/magic/__init__.py @@ -1,7 +1,31 @@ # -*- coding: utf-8 -*- -"""PRQL magic wrapping ipython-sql.""" -from IPython import get_ipython +"""IPython/Jupyter magic for PyPRQL. + +Examples +-------- +A single function is defined herein. +It should **_never_** be used directly by the user. +Rather, +any users should load the magic using the IPython line magic, +like below: + + In [1]: %load_ext pyprql.magic + +""" +from IPython import InteractiveShell from .prql import PRQLMagic -get_ipython().register_magics(PRQLMagic) + +def load_ipython_extension(ipython: InteractiveShell) -> None: + """Load the ``pyprql.magic`` extension. + + This function is called automatically by ``IPython`` when + the magic is loaded using ``%load_ext``. + + Parameters + ---------- + ipython: InteractiveShell + The current IPython instance. + """ + ipython.register_magics(PRQLMagic) diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py index d74df89..87791ab 100644 --- a/pyprql/magic/prql.py +++ b/pyprql/magic/prql.py @@ -16,7 +16,7 @@ class PRQLMagic(SqlMagic): This is a thin wrapper around ``sql.SqlMagic``, the class that provides the ``%%sql`` magic. For full documentation on usage and features, - please see their docs_. + please see their `docs `_. We override their defaults in two cases: @@ -28,8 +28,6 @@ class PRQLMagic(SqlMagic): we also provide an ``autoview`` option to indicate whether results should be printed to the window. - .. _docs: https://github.com/catherinedevlin/ipython-sql - Parameters ---------- shell : InteractiveShell @@ -56,15 +54,13 @@ def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: """Create the PRQL magic. To handle parsing to PRQL, - there is one limitation relative to the original_ ``%%sql`` magic. - Namely, + there is one limitation relative to the `original `_ + ``%%sql`` magic. Namely, line magics can only be used to pass connection strings and arguments. To figure out whether the ``line`` argument contained PRQL or not required heavy parsing followed by recosntruction of the input to pass on to the ``%sql`` magic we are wrapping. - .. _original: https://github.com/catherinedevlin/ipython-sql - Parameters ---------- line : str From 1a47609a0d23a66113b944fc30ba5ef105778da6 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Wed, 18 May 2022 16:10:45 +0100 Subject: [PATCH 08/14] style(magic/prql.py): apply lints Applies encessary lints to the file, while also updating format to run on Python 3.10/ --- noxfile.py | 2 +- pyprql/magic/prql.py | 13 +++---------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/noxfile.py b/noxfile.py index cc84e20..88b68e4 100644 --- a/noxfile.py +++ b/noxfile.py @@ -38,7 +38,7 @@ def constrained_install(session: Session, *args: str, **kwargs: Any) -> None: os.remove("requirements.txt") -@nox.session(python="3.8") +@nox.session(python="3.10") def form(session: Session) -> None: """Format code with isort and black.""" args = session.posargs or LOCATIONS diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py index 87791ab..79b5b63 100644 --- a/pyprql/magic/prql.py +++ b/pyprql/magic/prql.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """A magic class for parsing PRQL in IPython or Jupyter.""" -from typing import Any, Dict +from typing import Dict from IPython import InteractiveShell from IPython.core.magic import cell_magic, line_magic, magics_class, needs_local_scope @@ -44,13 +44,13 @@ class PRQLMagic(SqlMagic): ) autoview = Bool(True, config=True, help="Display results") - def __init__(self, shell: InteractiveShell): + def __init__(self, shell: InteractiveShell) -> None: super().__init__(shell) @needs_local_scope @line_magic @cell_magic - def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: + def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> None: """Create the PRQL magic. To handle parsing to PRQL, @@ -69,13 +69,6 @@ def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> Any: The magic's cell contents. local_ns : Dict The variables local to the running IPython shell. - - Returns - ------- - Any - Depending on the arguments passed, - this could be one of several items, - such as a ``sqlalchemy`` connection or a ``pandas`` dataframe. """ # If cell is occupied, it must be parsed to SQL if cell != "": From 44c7893b7bc59d20d4b0ceac0b969d94ffe5da8d Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Wed, 18 May 2022 16:55:56 +0100 Subject: [PATCH 09/14] build(actions): update lock file Bring pyproject and lock file into alignment and update cache number. --- .github/workflows/cicd.yaml | 2 +- poetry.lock | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/cicd.yaml b/.github/workflows/cicd.yaml index 8020851..90a1804 100644 --- a/.github/workflows/cicd.yaml +++ b/.github/workflows/cicd.yaml @@ -12,7 +12,7 @@ on: env: POETRY_VERSION: 1.1.13 PSR_VERSION: 7.28.1 - CACHE_NUMBER: 4 + CACHE_NUMBER: 5 jobs: form: diff --git a/poetry.lock b/poetry.lock index dfac7a2..d0405ce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -169,7 +169,7 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"] [[package]] name = "commitizen" -version = "2.26.0" +version = "2.27.0" description = "Python commitizen client tool" category = "dev" optional = false @@ -1150,14 +1150,14 @@ setuptools = "*" [[package]] name = "setuptools" -version = "62.2.0" +version = "62.3.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinxcontrib-towncrier", "furo"] +docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-reredirects", "sphinxcontrib-towncrier", "furo"] testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-enabler (>=1.0.1)", "pytest-perf", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "wheel", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "jaraco.path (>=3.2.0)", "build", "filelock (>=3.4.0)", "pip-run (>=8.8)", "ini2toml[lite] (>=0.9)", "tomli-w (>=1.0.0)", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy (>=0.9.1)"] testing-integration = ["pytest", "pytest-xdist", "pytest-enabler", "virtualenv (>=13.0.0)", "tomli", "wheel", "jaraco.path (>=3.2.0)", "jaraco.envs (>=2.2)", "build", "filelock (>=3.4.0)"] @@ -1553,8 +1553,8 @@ colorlog = [ {file = "colorlog-6.6.0.tar.gz", hash = "sha256:344f73204009e4c83c5b6beb00b3c45dc70fcdae3c80db919e0a4171d006fde8"}, ] commitizen = [ - {file = "commitizen-2.26.0-py3-none-any.whl", hash = "sha256:408fdc9527b3570425fb7e7a67d5e2e4269d7533d7ff91a88c63a382a8ae85c6"}, - {file = "commitizen-2.26.0.tar.gz", hash = "sha256:a999051d5a3b2e9cce86d01ef2ad05232e827fa256cab89658dded46bcf94081"}, + {file = "commitizen-2.27.0-py3-none-any.whl", hash = "sha256:846d8caf903499d3bf48a834cdc95dad48cd7e91a62717c4649f879e248348ae"}, + {file = "commitizen-2.27.0.tar.gz", hash = "sha256:ef18cfbf68df38b313f63ede2532dbbc62800030539544f4876a829897abd86c"}, ] commonmark = [ {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, @@ -2175,8 +2175,8 @@ safety = [ {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, ] setuptools = [ - {file = "setuptools-62.2.0-py3-none-any.whl", hash = "sha256:5534570b9980fc650d45c62877ff603c7aaaf24893371708736cc016bd221c3c"}, - {file = "setuptools-62.2.0.tar.gz", hash = "sha256:ca6ba73b7fd5f734ae70ece8c4c1f7062b07f3352f6428f6277e27c8f5c64237"}, + {file = "setuptools-62.3.1-py3-none-any.whl", hash = "sha256:588ffd1dc6e20e9f4f7057aa9873fcdc26e0270362602735d32476bad67d82c5"}, + {file = "setuptools-62.3.1.tar.gz", hash = "sha256:28c79c24d83c42a5e6d6cc711e5e9a6c1b89326229feaa5807fc277040658600"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, From c24228e2cdf4ee7c617d5f85a8762b331de70e4d Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Wed, 18 May 2022 17:07:44 +0100 Subject: [PATCH 10/14] build(poetry.lock): revert to v 1.1.13 Use of a local pre-release version of poetry had caused divergent formats in the lockfiles. This should bring those back in line. --- poetry.lock | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index d0405ce..63a4e4d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -483,7 +483,6 @@ pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" pygments = "*" -setuptools = ">=18.5" traitlets = ">=4.2" [package.extras] @@ -1146,20 +1145,6 @@ Click = ">=6.0" dparse = ">=0.5.1" packaging = "*" requests = "*" -setuptools = "*" - -[[package]] -name = "setuptools" -version = "62.3.1" -description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-reredirects", "sphinxcontrib-towncrier", "furo"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-enabler (>=1.0.1)", "pytest-perf", "mock", "flake8-2020", "virtualenv (>=13.0.0)", "wheel", "pip (>=19.1)", "jaraco.envs (>=2.2)", "pytest-xdist", "jaraco.path (>=3.2.0)", "build", "filelock (>=3.4.0)", "pip-run (>=8.8)", "ini2toml[lite] (>=0.9)", "tomli-w (>=1.0.0)", "pytest-black (>=0.3.7)", "pytest-cov", "pytest-mypy (>=0.9.1)"] -testing-integration = ["pytest", "pytest-xdist", "pytest-enabler", "virtualenv (>=13.0.0)", "tomli", "wheel", "jaraco.path (>=3.2.0)", "jaraco.envs (>=2.2)", "build", "filelock (>=3.4.0)"] [[package]] name = "six" @@ -1195,7 +1180,6 @@ Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" requests = ">=2.5.0" -setuptools = "*" snowballstemmer = ">=1.1" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" @@ -1468,7 +1452,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7.1" -content-hash = "194ef71e7e966207deab779aa98ea21475e65ae6d3e3fdf3d9fe0ce9600b4efe" +content-hash = "656601a5be57892d0d6c7a86693ce82a0b307de17df03a78733b139b3a6bdb6c" [metadata.files] alabaster = [ @@ -2174,10 +2158,6 @@ safety = [ {file = "safety-1.10.3-py2.py3-none-any.whl", hash = "sha256:5f802ad5df5614f9622d8d71fedec2757099705c2356f862847c58c6dfe13e84"}, {file = "safety-1.10.3.tar.gz", hash = "sha256:30e394d02a20ac49b7f65292d19d38fa927a8f9582cdfd3ad1adbbc66c641ad5"}, ] -setuptools = [ - {file = "setuptools-62.3.1-py3-none-any.whl", hash = "sha256:588ffd1dc6e20e9f4f7057aa9873fcdc26e0270362602735d32476bad67d82c5"}, - {file = "setuptools-62.3.1.tar.gz", hash = "sha256:28c79c24d83c42a5e6d6cc711e5e9a6c1b89326229feaa5807fc277040658600"}, -] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, From 1e0da72056c3e447c4e60385c5423da8f8695849 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Fri, 20 May 2022 09:59:59 +0100 Subject: [PATCH 11/14] docs(magic): expand line vs cell explanation Expands on our different uses of line and cell magic relative to IPython-SQL, and also corrects a few minor typos. --- pyprql/magic/README.md | 24 ++++++++++++++++++------ pyprql/magic/prql.py | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/pyprql/magic/README.md b/pyprql/magic/README.md index c75c934..81ecf46 100644 --- a/pyprql/magic/README.md +++ b/pyprql/magic/README.md @@ -4,7 +4,7 @@ Work with pandas and PRQL in an IPython terminal or Jupyter notebook. ## Implementation -This is a this wrapper around the fantastic +This is a thin wrapper around the fantastic [IPython-sql][ipysql] magic. Roughly speaking, all we do is parse PRQL to SQL and pass that through to `ipython-sql`. @@ -26,7 +26,7 @@ If you haven't installed PyPRQL, that's as simple as: ```shell -pip install PyPRQL +pip install pyprql ``` ### Set Up @@ -70,14 +70,26 @@ This adds a table named `data` to the in-memory `DuckDB` instance. If you connect to an existing SQL database, then all the tables normally there will be accessible. -### Usage +One thing we don't support that `IPython-SQL` does is passing PRQL directly to a line magic. +That is to say, +the following will **not** work: + +```python +In [4]: %prql from data | select freq + +``` -:::{Important} +This mainly to work around some parsing challenges, +and it may be added as a feature in a future release. + +:::{Warning} This is one area where we differe from `IPython-sql`. -We only support parasing PRQL as a cell magic, -not as a line magic. +PRQL queries can only be made from a cell magic. ::: + +### Usage + Now, let's do a query! By default, diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py index 79b5b63..f853d36 100644 --- a/pyprql/magic/prql.py +++ b/pyprql/magic/prql.py @@ -24,7 +24,7 @@ class PRQLMagic(SqlMagic): 1. displaycon is set to ``False``. Additionally, - to working around some quirky behaviour, + to work around some quirky behaviour, we also provide an ``autoview`` option to indicate whether results should be printed to the window. From f28d5cb6eb722f4d59a4db058b6ec8884c2b2fb8 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Fri, 20 May 2022 10:03:07 +0100 Subject: [PATCH 12/14] style(magic/prql.py): improve boolean checks Empty strings are falsey while non empty strings are truth, so we can check them directly. --- pyprql/magic/prql.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyprql/magic/prql.py b/pyprql/magic/prql.py index f853d36..40a8546 100644 --- a/pyprql/magic/prql.py +++ b/pyprql/magic/prql.py @@ -71,12 +71,12 @@ def prql(self, line: str = "", cell: str = "", local_ns: Dict = {}) -> None: The variables local to the running IPython shell. """ # If cell is occupied, it must be parsed to SQL - if cell != "": + if cell: cell = to_sql(cell) # If cell is occupied and line is empty, # we artificially populate line to ensure a return value. - if cell != "" and line == "": + if cell and not line: line = "_ <<" super().execute(line=line, cell=cell, local_ns=local_ns) From c70324b8502cb57e411ce8a1179c2cf3c8efbe4e Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Fri, 20 May 2022 10:08:06 +0100 Subject: [PATCH 13/14] build(pyproject.toml): improver IPython version specification Allows those running more recent versions of Python to use more recent versions of IPython. --- poetry.lock | 74 +++++++++++++++++++++++++++++++++++++++++++++++++- pyproject.toml | 5 +++- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index 63a4e4d..4f47c50 100644 --- a/poetry.lock +++ b/poetry.lock @@ -496,6 +496,41 @@ parallel = ["ipyparallel"] qtconsole = ["qtconsole"] test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] +[[package]] +name = "ipython" +version = "8.3.0" +description = "IPython: Productive Interactive Computing" +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" + +[package.extras] +all = ["black", "Sphinx (>=1.3)", "ipykernel", "nbconvert", "nbformat", "ipywidgets", "notebook", "ipyparallel", "qtconsole", "pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "numpy (>=1.19)", "pandas", "trio"] +black = ["black"] +doc = ["Sphinx (>=1.3)"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test_extra = ["pytest (<7.1)", "pytest-asyncio", "testpath", "curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.19)", "pandas", "trio"] + [[package]] name = "ipython-genutils" version = "0.2.0" @@ -907,6 +942,17 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +tests = ["pytest"] + [[package]] name = "py" version = "1.11.0" @@ -1320,6 +1366,22 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "stack-data" +version = "0.2.0" +description = "Extract data from python stack frames and tracebacks for informative displays" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +asttokens = "*" +executing = "*" +pure-eval = "*" + +[package.extras] +tests = ["pytest", "typeguard", "pygments", "littleutils", "cython"] + [[package]] name = "termcolor" version = "1.1.0" @@ -1452,7 +1514,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest- [metadata] lock-version = "1.1" python-versions = "^3.7.1" -content-hash = "656601a5be57892d0d6c7a86693ce82a0b307de17df03a78733b139b3a6bdb6c" +content-hash = "c8cc6c8ca5f619b4f3bb4a15def507d56c6148d431596ab02a29d4c702106d75" [metadata.files] alabaster = [ @@ -1775,6 +1837,8 @@ iniconfig = [ ipython = [ {file = "ipython-7.33.0-py3-none-any.whl", hash = "sha256:916a3126896e4fd78dd4d9cf3e21586e7fd93bae3f1cd751588b75524b64bf94"}, {file = "ipython-7.33.0.tar.gz", hash = "sha256:bcffb865a83b081620301ba0ec4d95084454f26b91d6d66b475bff3dfb0218d4"}, + {file = "ipython-8.3.0-py3-none-any.whl", hash = "sha256:341456643a764c28f670409bbd5d2518f9b82c013441084ff2c2fc999698f83b"}, + {file = "ipython-8.3.0.tar.gz", hash = "sha256:807ae3cf43b84693c9272f70368440a9a7eaa2e7e6882dad943c32fbf7e51402"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -2053,6 +2117,10 @@ ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] +pure-eval = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, @@ -2240,6 +2308,10 @@ sqlparse = [ {file = "sqlparse-0.4.2-py3-none-any.whl", hash = "sha256:48719e356bb8b42991bdbb1e8b83223757b93789c00910a616a071910ca4a64d"}, {file = "sqlparse-0.4.2.tar.gz", hash = "sha256:0c00730c74263a94e5a9919ade150dfc3b19c574389985446148402998287dae"}, ] +stack-data = [ + {file = "stack_data-0.2.0-py3-none-any.whl", hash = "sha256:999762f9c3132308789affa03e9271bbbe947bf78311851f4d485d8402ed858e"}, + {file = "stack_data-0.2.0.tar.gz", hash = "sha256:45692d41bd633a9503a5195552df22b583caf16f0b27c4e58c98d88c8b648e12"}, +] termcolor = [ {file = "termcolor-1.1.0.tar.gz", hash = "sha256:1d6d69ce66211143803fbc56652b41d73b4a400a2891d7bf7a1cdf4c02de613b"}, ] diff --git a/pyproject.toml b/pyproject.toml index 90796c9..1857d3c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,10 @@ numpy = [ {version = "^1.22.3", python = "^3.8"} ] prql-python = "^0" -ipython = "7.33.0" +ipython = [ + {version = "~7.33.0", python = "~3.7.1"}, + {version = "^8.0", python = "^3.8"} +] ipython-sql = "^0.4.0" duckdb-engine = "^0.1.8" traitlets = "^5.2.0" From d555db037c00cbcc76b57b2d820235ef540810c9 Mon Sep 17 00:00:00 2001 From: rbpatt2019 Date: Sat, 21 May 2022 07:11:07 +0100 Subject: [PATCH 14/14] docs(magic/README.md): correct typos --- pyprql/magic/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyprql/magic/README.md b/pyprql/magic/README.md index 81ecf46..9752878 100644 --- a/pyprql/magic/README.md +++ b/pyprql/magic/README.md @@ -70,7 +70,7 @@ This adds a table named `data` to the in-memory `DuckDB` instance. If you connect to an existing SQL database, then all the tables normally there will be accessible. -One thing we don't support that `IPython-SQL` does is passing PRQL directly to a line magic. +One thing we don't support that `IPython-SQL` does is passing a PRQL query directly to a line magic. That is to say, the following will **not** work: @@ -83,7 +83,7 @@ This mainly to work around some parsing challenges, and it may be added as a feature in a future release. :::{Warning} -This is one area where we differe from `IPython-sql`. +This is one area where we differ from `IPython-sql`. PRQL queries can only be made from a cell magic. :::