tab-cli 0.1.5__tar.gz → 0.1.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tab_cli-0.1.5 → tab_cli-0.1.7}/AGENTS.md +1 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/CHANGELOG.md +5 -0
- tab_cli-0.1.7/PKG-INFO +121 -0
- tab_cli-0.1.7/README.md +94 -0
- tab_cli-0.1.7/docs/configuration.md +34 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/mkdocs.yml +1 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/pyproject.toml +3 -3
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/cli.py +95 -27
- tab_cli-0.1.7/src/tab_cli/config.py +47 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/formats/parquet.py +1 -1
- {tab_cli-0.1.5 → tab_cli-0.1.7}/tests/test_cli.py +164 -14
- tab_cli-0.1.5/PKG-INFO +0 -37
- tab_cli-0.1.5/README.md +0 -10
- tab_cli-0.1.5/src/tab_cli/config.py +0 -15
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.gitignore +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/.gitignore +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/282ad8cf3324b2679a7d460c0fc324adfa21dcfad2f197ac6991b98ec91f98495bb3ddb2cba36ce5dfa28a52063a373bb03f5d2e34f6e0c7b6b81b3046a4d7d0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/891d7ed26f62b0f8757b081e9d76840636877f1613ee17b7695fe2ee8640258c56e01291934e3797728bc2300a1b5f41e3f3ef81ab532c0e5ab475bb9b6f097a +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/8926397375b8328137652c18cd4371808b214cb26864d77dd33c8eea895e10e62c297064c3d4c703d58ee11dee81bbf9851525e3a0c33151f54c164b8a4343b0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/89d29d938e64b1295e138faedfa5df6f6729a67e5ba8e0c3fdd1c9266e0f59a4bc35b8a21e14225072317879af3323fa0457e01d9b08608770bc23957feec6c0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/95fc2854c0fa2528b03e2bcabc7612f56f0bcb3d6f54a06293e21d1887885a449907b5b320a1a94bac712bf56fdad0a4184b17047c1fc179dfa83acab3f70d21 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/9a58ceae46de4649375b6b880b8500c85d34c8e9bc650dc4c993afb2fa8d45c4180331821c6226a0fb1475b04a0b9a849502647ef9c4dcac74769eb501c885fa +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/a19ae062208aa20b7310705af3d26ef53095a9dabfad080883cc7a32e98687063179db95cb2c71ef9064801c59fa46d261f172d83e83f96a39c274387b59dca4 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/d1169a8d10067493e42752c2a7615ff27f55bd90c38b91feef918958e29a2239ee289a0cde8385441d1f0fe9af1fb634fa6d56438b9f33ec382e81fa59d70b54 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/e171e5c6039c050c2368584a537d36df221b1f9f23d285c0399b95b14608d67006229823e6831bff7d8b0c2f9e86ebaec9c6811461119195f430ade055073fed +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/op_links/ee118dd19aac4e1cb354f83a37dadca70bc5f086cc8d36cd0059b222bf8c7250824401ff681518d0120f8db1f96f0025c464dcfc3b1ee28777e8c76325760134 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/282ad8cf3324b2679a7d460c0fc324adfa21dcfad2f197ac6991b98ec91f98495bb3ddb2cba36ce5dfa28a52063a373bb03f5d2e34f6e0c7b6b81b3046a4d7d0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/891d7ed26f62b0f8757b081e9d76840636877f1613ee17b7695fe2ee8640258c56e01291934e3797728bc2300a1b5f41e3f3ef81ab532c0e5ab475bb9b6f097a +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/8926397375b8328137652c18cd4371808b214cb26864d77dd33c8eea895e10e62c297064c3d4c703d58ee11dee81bbf9851525e3a0c33151f54c164b8a4343b0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/89d29d938e64b1295e138faedfa5df6f6729a67e5ba8e0c3fdd1c9266e0f59a4bc35b8a21e14225072317879af3323fa0457e01d9b08608770bc23957feec6c0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/95fc2854c0fa2528b03e2bcabc7612f56f0bcb3d6f54a06293e21d1887885a449907b5b320a1a94bac712bf56fdad0a4184b17047c1fc179dfa83acab3f70d21 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/9a58ceae46de4649375b6b880b8500c85d34c8e9bc650dc4c993afb2fa8d45c4180331821c6226a0fb1475b04a0b9a849502647ef9c4dcac74769eb501c885fa +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/a19ae062208aa20b7310705af3d26ef53095a9dabfad080883cc7a32e98687063179db95cb2c71ef9064801c59fa46d261f172d83e83f96a39c274387b59dca4 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/d1169a8d10067493e42752c2a7615ff27f55bd90c38b91feef918958e29a2239ee289a0cde8385441d1f0fe9af1fb634fa6d56438b9f33ec382e81fa59d70b54 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/e171e5c6039c050c2368584a537d36df221b1f9f23d285c0399b95b14608d67006229823e6831bff7d8b0c2f9e86ebaec9c6811461119195f430ade055073fed +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/operations/ee118dd19aac4e1cb354f83a37dadca70bc5f086cc8d36cd0059b222bf8c7250824401ff681518d0120f8db1f96f0025c464dcfc3b1ee28777e8c76325760134 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/1029dd1c1f4430d8a667a0e48d0b817652c7ddca6f5ff56cac1755e5bb0c1cb7586935941c9b36f26cab05c0effe6154d073bd1dffbe37f22fed0a6e7d79201f +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/3228b9bef9d8374b5532b40df2da8be3bfc86de713bdad7fe620977ffa7c56db83928678caa792bf0d328db607028e045a9e41423ef7501e5b550651c3815ffe +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/424c9a53f5458b328d77ed6a943dc35662e949befa8725cfc7eead01a270417c8d07c1001b11623a088da8d2c9c34a41573314fa2394643147e4027e8a96a605 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/44107e81054aa5544b36eab8d811908a559b4d9027dc3fa1762c44e39551652199ef2a31f9bbcda79773c906151c12578cb18c43e0045de8b20c357272e1c62a +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/52ea57bde33e8ef4718d833c2df3cf0a9e90fdcd5715c0caad50b4e37ea60aca2b8c71096de6920dc936c40b6291e896293f91c7cfd2aa96cf6c2aa49ef662c8 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/5ea52f6d4771afda4747b9f44954102c02ae2d0686f8aa9eca36c29796bbba0d14e851c0dca0a6af17bfbbbac174e3be645ae708d958390168e85c64786fc9ef +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/86a1cfa113399acc7dd2dc90262a845558affb5e9373b6300dff68a485482c5e17ace9466bbc23b4301013ca1a27a577ca57ea838113f45bf321a64a242b1ad3 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/8ef99a12ae0624db198d9ecd83014fb8353c4731e0ba9a472f1fc339784308e38f1287d0765a7b0444f1a89c218c76a820dc4c9a3a39c1cedcd7423a4f5f88dc +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/cb3e8da2bf2b7efae4a6e8fd0b8562dacd16ca0531b173a91480a9e60ee795ac5bec13fc6eb461e03edc9a26f5ff1d5ba53521a1c1a6c1ee1765b544b7d7bf73 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/segments/d27ad326963b75736b636adad9fb812eb3f2871e0efb4bc7db37d4b701a4282911eaaee91bed3a759e940769b667be1ed66f2d7f2f41ac3906b87ab7eec19c3a +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/index/type +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_heads/heads/891d7ed26f62b0f8757b081e9d76840636877f1613ee17b7695fe2ee8640258c56e01291934e3797728bc2300a1b5f41e3f3ef81ab532c0e5ab475bb9b6f097a +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_heads/type +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/282ad8cf3324b2679a7d460c0fc324adfa21dcfad2f197ac6991b98ec91f98495bb3ddb2cba36ce5dfa28a52063a373bb03f5d2e34f6e0c7b6b81b3046a4d7d0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/891d7ed26f62b0f8757b081e9d76840636877f1613ee17b7695fe2ee8640258c56e01291934e3797728bc2300a1b5f41e3f3ef81ab532c0e5ab475bb9b6f097a +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/8926397375b8328137652c18cd4371808b214cb26864d77dd33c8eea895e10e62c297064c3d4c703d58ee11dee81bbf9851525e3a0c33151f54c164b8a4343b0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/89d29d938e64b1295e138faedfa5df6f6729a67e5ba8e0c3fdd1c9266e0f59a4bc35b8a21e14225072317879af3323fa0457e01d9b08608770bc23957feec6c0 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/95fc2854c0fa2528b03e2bcabc7612f56f0bcb3d6f54a06293e21d1887885a449907b5b320a1a94bac712bf56fdad0a4184b17047c1fc179dfa83acab3f70d21 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/9a58ceae46de4649375b6b880b8500c85d34c8e9bc650dc4c993afb2fa8d45c4180331821c6226a0fb1475b04a0b9a849502647ef9c4dcac74769eb501c885fa +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/a19ae062208aa20b7310705af3d26ef53095a9dabfad080883cc7a32e98687063179db95cb2c71ef9064801c59fa46d261f172d83e83f96a39c274387b59dca4 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/d1169a8d10067493e42752c2a7615ff27f55bd90c38b91feef918958e29a2239ee289a0cde8385441d1f0fe9af1fb634fa6d56438b9f33ec382e81fa59d70b54 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/e171e5c6039c050c2368584a537d36df221b1f9f23d285c0399b95b14608d67006229823e6831bff7d8b0c2f9e86ebaec9c6811461119195f430ade055073fed +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/operations/ee118dd19aac4e1cb354f83a37dadca70bc5f086cc8d36cd0059b222bf8c7250824401ff681518d0120f8db1f96f0025c464dcfc3b1ee28777e8c76325760134 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/type +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/123b0e36150cf8e99d644d2dfd1a7b0c8d2f676a78248d6902516d9ae58903665c79ec3f5f6729b98a1237dcf2abc1d41e690ae0ad30888c84786bcc9de5e314 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/2ac0b7d8b1fdfac82b3ff3926e0018f72ef2b48f85b41f5fa541271370e1197d41e37c2c6d62af0c6974658c4a9e5e945b8efcbcc7748bdd99bd9483f7e13e22 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/67b8396b301935ff624ff98952c57d8ee021e7d885e1220053b993e7bc822a4cf061298e9643ded745c55f3ed8e923a6731524129993d2664f48b60660761145 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/9c6fca696f77383cc87d068fe3f5912466b157dccc6465973e653dd4d2c02e2eca9c0725c071857bf3f4f0e263259eafc18f1739615a501e672bb2afd415316b +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/cae2e3e5952cb5ba93f27e3898d90dac6c41fc9e20c66ef0791e71b91dc103d924996c921c88179705264a224fb5d2bb29091fc8f18f0ea7a088aaabb859ea2a +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/cd8efb6da14127c81c37b56ead18a39b30f2cd154891185a6e906efb491dbf63f290eed3c31d4725f490a93208ffbe5cdc031d5b6de38fcb77cbb11f0357118f +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/e434359d6306a4f6997733b9b5308299984f05219c92e1b2a31f1203126be0fada5fc09a2ba86c98d1318981cb53997c7f8674ef25da6ca7bf9fd849598cd355 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/ea75e7ccb42f52b013dc1b45bb4e6d692b37c5e38bd39356ba2806be83ca5ca03ce20481db2788428126f93663e6723f99f4d46c5c705f5b12b70e2127ab15ba +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/fa5dec7ee06fbc6cbb2798c8e98bab482a6750776de41406fb06893c83f71f5015ec7ee2873642714b7bbc1c496f880e3acf44ffdabf2f87a39e0fbd68a4cc46 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/op_store/views/ffde172c6285c71851b22780e34962d8f9234067af59ff2dc38b74e905dc540fe35b944e8c0b2d4230dfcf778424a335494cd0aeea1bb4be2a11c4b5428ad465 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/14e3f15273e204cadfe38dd2f38cebd1343a6bfbb91c6af0f5f9de6e9003d8ec8b0eb676975af9dca2d06ee5e6b3886c3c5d3755c6f149b6b09172cccc35adff +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/42e0f32dd10ba6ae9f2297ca8ad0bd16337f14545b29f956ce380a7ab92bab771cbc9e04755752a6fa13231286f724379d6662b0fb257ef2cc2c52fe680eb95d +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/466a441e56afdde383cef1d6127ca1d4c825157feb65a59f8f6ff5fa7a523bd683d0b7a6bb16c00afff53a890319a472d98da9af3dea5675168a4d424aa7af32 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/482ae5a29fbe856c7272f2071b8b0f0359ee2d89ff392b8a900643fbd0836eccd067b8bf41909e206c90d45d6e7d8b6686b93ecaee5fe1a9060d87b672101310 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/5403fa06049419ddcf620ce0dc20911583e1b1062b42630ee325aa5ac2f918dd266dfed93ebc808a2aecb37ac3a33e251fe1396fd24b8ed566bfbd61a81ff959 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/56119fa0480cb66159978b1a8c9b031f9e978b7a3172eb87407a701fea34fdd90db7771cd433a2cf7e8a84a7b49c924f973eccb0eb05685ec42f36f7ef61cc06 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/90b1f4de4ba65e0652f1de45e4c84b623f99bd9d9453667e19c7040857bd397e59e7a84406f2ab6204d25789d995c47c350d8abc47a4bbb102059f3111f20028 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/9215bd4ac28fdecba111c63bace46d0f1c253ad3af44e0e74bd43d30757bef2e655538c1172c8f25769bce0a3c669b713440773c1859f0a136d9ca42501f2470 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/a79320f784ef97b3d6297e55a48b17a517a38d95d5c61ba8d01c59d68dcd2ccf3a96479f4fc3c4cafdcd56dc7bd58b1cb987e079764c1646533ab32418900727 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/abe6b7a350e1604cb8f5a2cd10cef13a019bd797770e6dc37414d33d98dcf36d8ec80a2ae13bd7dd2d2076772c0ffadec0b53ba72f4669b461fff2da5d30f1ba +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/b7689d54193a3798edd58d758966ad65ad57297c5276eab3e4ef07380779363efe9e462a149f4d42f55bbe004eb5ba88bf35df4c78ac975275530382390159d6 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/e75f5f3431d172d7e9434dfaef2be50812105b3ead73eeb10345c9b6892e9cbb5ee0602ebb0ceaf5ab87d22f45930dc30d136d0aac77310fb0261b3857ffde9b +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/extra/heads/56119fa0480cb66159978b1a8c9b031f9e978b7a3172eb87407a701fea34fdd90db7771cd433a2cf7e8a84a7b49c924f973eccb0eb05685ec42f36f7ef61cc06 +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/git_target +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/store/type +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/submodule_store/type +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/repo/workspace_store/index +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/working_copy/checkout +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/working_copy/tree_state +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/.jj/working_copy/type +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/LICENSE +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/Makefile +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/docs/cli-ref.md +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/docs/cloud.md +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/docs/gen_assets.sh +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/docs/index.md +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/__init__.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/formats/__init__.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/formats/avro.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/formats/base.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/formats/csv.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/formats/jsonl.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/handlers/__init__.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/handlers/base.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/handlers/cli_table.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/storage/__init__.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/storage/aws.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/storage/az.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/storage/base.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/storage/fsspec.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/storage/gcloud.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/storage/local.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/style.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/src/tab_cli/url_parser.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/tests/__init__.py +0 -0
- {tab_cli-0.1.5 → tab_cli-0.1.7}/tests/assets/test.csv +0 -0
|
@@ -143,6 +143,7 @@ Use it as the default operating guide when changing code in this repo.
|
|
|
143
143
|
## Documentation
|
|
144
144
|
|
|
145
145
|
- Update `docs/` and CLI help text when changing user-facing behavior.
|
|
146
|
+
- Update `CHANGELOG.md` with a clear description of user-facing changes and bug fixes.
|
|
146
147
|
- Keep examples aligned with the actual command names and flags.
|
|
147
148
|
- If you change build, test, or auth flows, reflect that in this file too.
|
|
148
149
|
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
- 0.1.7:
|
|
2
|
+
- Optional dependency groups are now named `tab-cli[s3|gs|az]`, in accordance with the protocol name.
|
|
3
|
+
- 0.1.6:
|
|
4
|
+
- Fixed bug in pyarrow loading of Parquet files.
|
|
5
|
+
- Added global config file support: settings can be persisted in `~/.config/tab/config.json`. Config file values serve as defaults that CLI flags override.
|
|
1
6
|
- 0.1.5:
|
|
2
7
|
- Added stdin support: use `-` as the file path to read from stdin (e.g. `cat data.csv | tab view -i csv -`). Requires `-i`/`--input-format` since format cannot be inferred. Works with `view`, `schema`, `summary`, `convert`, and `cat`.
|
|
3
8
|
- Added row-wise JMESPath queries via `--jmespath` / `--jp` on `view`, `convert`, and `cat`. Object results become columns; non-object results go into a `value` column. `--sql` and `--jp` are mutually exclusive.
|
tab_cli-0.1.7/PKG-INFO
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tab-cli
|
|
3
|
+
Version: 0.1.7
|
|
4
|
+
Summary: A CLI tool for tabular data
|
|
5
|
+
Author-email: Tongfei Chen <tongfei@pm.me>
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: blobfile>=3.0
|
|
9
|
+
Requires-Dist: fsspec>=2025.1.0
|
|
10
|
+
Requires-Dist: jmespath>=1.0
|
|
11
|
+
Requires-Dist: loguru>=0.7.3
|
|
12
|
+
Requires-Dist: polars-fastavro>=0.5.1
|
|
13
|
+
Requires-Dist: polars>=1.0
|
|
14
|
+
Requires-Dist: pyarrow>=15.0
|
|
15
|
+
Requires-Dist: rich>=13.0
|
|
16
|
+
Requires-Dist: typer>=0.21.1
|
|
17
|
+
Provides-Extra: az
|
|
18
|
+
Requires-Dist: adlfs>=2025.1.0; extra == 'az'
|
|
19
|
+
Requires-Dist: azure-identity>=1.10.0; extra == 'az'
|
|
20
|
+
Provides-Extra: gs
|
|
21
|
+
Requires-Dist: gcsfs>=2025.1.0; extra == 'gs'
|
|
22
|
+
Requires-Dist: google-auth>=2.27.0; extra == 'gs'
|
|
23
|
+
Provides-Extra: s3
|
|
24
|
+
Requires-Dist: boto3>=1.28.0; extra == 's3'
|
|
25
|
+
Requires-Dist: s3fs>=2025.1.0; extra == 's3'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# tab
|
|
29
|
+
|
|
30
|
+
[](https://pypi.org/project/tab-cli/)
|
|
31
|
+
|
|
32
|
+
A CLI tool for viewing, querying, and converting tabular data files.
|
|
33
|
+
Reads CSV, TSV, JSON Lines, Parquet, and Avro -- locally or from S3, GCS, and Azure Blob Storage.
|
|
34
|
+
|
|
35
|
+
```sh
|
|
36
|
+
pip install tab-cli
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Documentation**: [tongfei.me/tab](https://tongfei.me/tab)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Quick look
|
|
44
|
+
|
|
45
|
+
### View any tabular file
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
tab view data.csv
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
<p align="center">
|
|
52
|
+
<img src="https://raw.githubusercontent.com/ctongfei/tab/refs/heads/gh-pages/assets/test.svg" alt="tab view" width="680">
|
|
53
|
+
</p>
|
|
54
|
+
|
|
55
|
+
### Query with SQL
|
|
56
|
+
|
|
57
|
+
The table is always available as `t`:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
tab view --sql 'SELECT * FROM t WHERE Metric_A_Value > 80' data.csv
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
<p align="center">
|
|
64
|
+
<img src="https://raw.githubusercontent.com/ctongfei/tab/refs/heads/gh-pages/assets/test-where.svg" alt="tab view --sql" width="680">
|
|
65
|
+
</p>
|
|
66
|
+
|
|
67
|
+
### Reshape rows with JMESPath
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
tab view --jp '{id: participant.id, city: profile.address.city}' data.parquet
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Convert between formats
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
tab convert data.csv data.parquet
|
|
77
|
+
tab convert data.parquet data.jsonl -o jsonl
|
|
78
|
+
tab convert data.csv output_dir/ -o parquet -n 4 # partitioned
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Concatenate files
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
tab cat part1.csv part2.csv part3.csv -o jsonl > combined.jsonl
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Inspect schema and summary
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
tab schema data.parquet
|
|
91
|
+
tab summary data.parquet
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Read from stdin
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
curl -s https://example.com/data.csv | tab view -i csv -
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Read from cloud storage
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
tab view s3://bucket/path/data.parquet
|
|
104
|
+
tab view gs://bucket/path/data.csv
|
|
105
|
+
tab view az://container/path/data.jsonl
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Install cloud extras as needed:
|
|
109
|
+
|
|
110
|
+
```sh
|
|
111
|
+
pip install 'tab-cli[s3]' # AWS S3
|
|
112
|
+
pip install 'tab-cli[gs]' # Google Cloud Storage
|
|
113
|
+
pip install 'tab-cli[az]' # Azure Blob Storage
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Supported formats
|
|
117
|
+
- csv
|
|
118
|
+
- tsv
|
|
119
|
+
- jsonl
|
|
120
|
+
- parquet
|
|
121
|
+
- avro
|
tab_cli-0.1.7/README.md
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# tab
|
|
2
|
+
|
|
3
|
+
[](https://pypi.org/project/tab-cli/)
|
|
4
|
+
|
|
5
|
+
A CLI tool for viewing, querying, and converting tabular data files.
|
|
6
|
+
Reads CSV, TSV, JSON Lines, Parquet, and Avro -- locally or from S3, GCS, and Azure Blob Storage.
|
|
7
|
+
|
|
8
|
+
```sh
|
|
9
|
+
pip install tab-cli
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
**Documentation**: [tongfei.me/tab](https://tongfei.me/tab)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Quick look
|
|
17
|
+
|
|
18
|
+
### View any tabular file
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
tab view data.csv
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
<p align="center">
|
|
25
|
+
<img src="https://raw.githubusercontent.com/ctongfei/tab/refs/heads/gh-pages/assets/test.svg" alt="tab view" width="680">
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
### Query with SQL
|
|
29
|
+
|
|
30
|
+
The table is always available as `t`:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
tab view --sql 'SELECT * FROM t WHERE Metric_A_Value > 80' data.csv
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
<p align="center">
|
|
37
|
+
<img src="https://raw.githubusercontent.com/ctongfei/tab/refs/heads/gh-pages/assets/test-where.svg" alt="tab view --sql" width="680">
|
|
38
|
+
</p>
|
|
39
|
+
|
|
40
|
+
### Reshape rows with JMESPath
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
tab view --jp '{id: participant.id, city: profile.address.city}' data.parquet
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Convert between formats
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
tab convert data.csv data.parquet
|
|
50
|
+
tab convert data.parquet data.jsonl -o jsonl
|
|
51
|
+
tab convert data.csv output_dir/ -o parquet -n 4 # partitioned
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Concatenate files
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
tab cat part1.csv part2.csv part3.csv -o jsonl > combined.jsonl
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Inspect schema and summary
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
tab schema data.parquet
|
|
64
|
+
tab summary data.parquet
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Read from stdin
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
curl -s https://example.com/data.csv | tab view -i csv -
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Read from cloud storage
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
tab view s3://bucket/path/data.parquet
|
|
77
|
+
tab view gs://bucket/path/data.csv
|
|
78
|
+
tab view az://container/path/data.jsonl
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Install cloud extras as needed:
|
|
82
|
+
|
|
83
|
+
```sh
|
|
84
|
+
pip install 'tab-cli[s3]' # AWS S3
|
|
85
|
+
pip install 'tab-cli[gs]' # Google Cloud Storage
|
|
86
|
+
pip install 'tab-cli[az]' # Azure Blob Storage
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
## Supported formats
|
|
90
|
+
- csv
|
|
91
|
+
- tsv
|
|
92
|
+
- jsonl
|
|
93
|
+
- parquet
|
|
94
|
+
- avro
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
`tab` supports a global configuration file at `~/.config/tab/config.json`. Settings in this file serve as defaults and are overridden by CLI flags.
|
|
4
|
+
|
|
5
|
+
## Setup
|
|
6
|
+
|
|
7
|
+
Create the config file:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
mkdir -p ~/.config/tab
|
|
11
|
+
cat > ~/.config/tab/config.json << 'EOF'
|
|
12
|
+
{
|
|
13
|
+
"az_url_authority_is_account": false,
|
|
14
|
+
"sampling_size_for_schema_inference": 32
|
|
15
|
+
}
|
|
16
|
+
EOF
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Available settings
|
|
20
|
+
|
|
21
|
+
| Key | Type | Default | Description |
|
|
22
|
+
|-----|------|---------|-------------|
|
|
23
|
+
| `az_url_authority_is_account` | `bool` | `false` | Interpret `az://` URL authority as storage account name instead of container name. |
|
|
24
|
+
| `sampling_size_for_schema_inference` | `int` | `32` | Number of rows sampled for schema inference (e.g. when using `--jp`). |
|
|
25
|
+
|
|
26
|
+
## Precedence
|
|
27
|
+
|
|
28
|
+
Settings are applied in this order (last wins):
|
|
29
|
+
|
|
30
|
+
1. Built-in defaults
|
|
31
|
+
2. Config file (`~/.config/tab/config.json`)
|
|
32
|
+
3. CLI flags (e.g. `--az-url-authority-is-account`)
|
|
33
|
+
|
|
34
|
+
If the config file does not exist, built-in defaults are used. Unknown keys in the file are ignored with a warning.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "tab-cli"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.7"
|
|
4
4
|
description = "A CLI tool for tabular data"
|
|
5
5
|
authors = [{name = "Tongfei Chen", email = "tongfei@pm.me"}]
|
|
6
6
|
readme = "README.md"
|
|
@@ -20,8 +20,8 @@ dependencies = [
|
|
|
20
20
|
|
|
21
21
|
[project.optional-dependencies]
|
|
22
22
|
s3 = ["s3fs>=2025.1.0", "boto3>=1.28.0"]
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
gs = ["gcsfs>=2025.1.0", "google-auth>=2.27.0"]
|
|
24
|
+
az = ["adlfs>=2025.1.0", "azure-identity>=1.10.0"]
|
|
25
25
|
|
|
26
26
|
[dependency-groups]
|
|
27
27
|
dev = [
|
|
@@ -12,27 +12,67 @@ from rich.console import Console
|
|
|
12
12
|
from rich.logging import RichHandler
|
|
13
13
|
|
|
14
14
|
from tab_cli import config
|
|
15
|
-
from tab_cli.config import Config
|
|
16
|
-
from tab_cli.handlers import
|
|
15
|
+
from tab_cli.config import Config, load_config_file
|
|
16
|
+
from tab_cli.handlers import (
|
|
17
|
+
TableWriter,
|
|
18
|
+
infer_reader,
|
|
19
|
+
infer_writer,
|
|
20
|
+
is_stdin,
|
|
21
|
+
read_stdin,
|
|
22
|
+
)
|
|
17
23
|
from tab_cli.handlers.base import TableSchema, TableSummary
|
|
18
24
|
|
|
19
25
|
# Reusable type aliases for common CLI options
|
|
20
|
-
PathArg: TypeAlias = Annotated[
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
26
|
+
PathArg: TypeAlias = Annotated[
|
|
27
|
+
str, typer.Argument(help="Path to the data file or directory")
|
|
28
|
+
]
|
|
29
|
+
PathsArg: TypeAlias = Annotated[
|
|
30
|
+
list[str], typer.Argument(help="Paths to the data files or directories")
|
|
31
|
+
]
|
|
32
|
+
SrcArg: TypeAlias = Annotated[
|
|
33
|
+
str, typer.Argument(help="Path to the source file or directory")
|
|
34
|
+
]
|
|
35
|
+
DstArg: TypeAlias = Annotated[
|
|
36
|
+
str, typer.Argument(help="Path to the destination file or directory")
|
|
37
|
+
]
|
|
38
|
+
InputOpt: TypeAlias = Annotated[
|
|
39
|
+
Optional[str],
|
|
40
|
+
typer.Option(
|
|
41
|
+
"-i",
|
|
42
|
+
"--input-format",
|
|
43
|
+
help="Input format, auto-detected from extension if omitted",
|
|
44
|
+
),
|
|
45
|
+
]
|
|
46
|
+
OutputOpt: TypeAlias = Annotated[
|
|
47
|
+
Optional[str], typer.Option("-o", "--output-format", help="Output format")
|
|
48
|
+
]
|
|
49
|
+
SqlOpt: TypeAlias = Annotated[
|
|
50
|
+
Optional[str],
|
|
51
|
+
typer.Option("--sql", help="SQL query to apply (table is available as 't')"),
|
|
52
|
+
]
|
|
27
53
|
JmespathOpt: TypeAlias = Annotated[
|
|
28
54
|
Optional[str],
|
|
29
|
-
typer.Option(
|
|
55
|
+
typer.Option(
|
|
56
|
+
"--jmespath", "--jp", help="JMESPath expression to apply to each row as JSON"
|
|
57
|
+
),
|
|
58
|
+
]
|
|
59
|
+
LimitOpt: TypeAlias = Annotated[
|
|
60
|
+
Optional[int], typer.Option("--limit", help="Maximum number of rows to display")
|
|
61
|
+
]
|
|
62
|
+
SkipOpt: TypeAlias = Annotated[
|
|
63
|
+
int, typer.Option("--skip", help="Number of rows to skip")
|
|
64
|
+
]
|
|
65
|
+
MaxCellLenOpt: TypeAlias = Annotated[
|
|
66
|
+
Optional[int],
|
|
67
|
+
typer.Option("--max-cell-len", help="Truncate cell contents longer than this"),
|
|
68
|
+
]
|
|
69
|
+
TableSvgOpt: TypeAlias = Annotated[
|
|
70
|
+
bool, typer.Option("--table-svg", help="Output table as SVG")
|
|
71
|
+
]
|
|
72
|
+
NumPartitionsOpt: TypeAlias = Annotated[
|
|
73
|
+
Optional[int],
|
|
74
|
+
typer.Option("-n", "--num-partitions", help="Number of output partitions"),
|
|
30
75
|
]
|
|
31
|
-
LimitOpt: TypeAlias = Annotated[Optional[int], typer.Option("--limit", help="Maximum number of rows to display")]
|
|
32
|
-
SkipOpt: TypeAlias = Annotated[int, typer.Option("--skip", help="Number of rows to skip")]
|
|
33
|
-
MaxCellLenOpt: TypeAlias = Annotated[Optional[int], typer.Option("--max-cell-len", help="Truncate cell contents longer than this")]
|
|
34
|
-
TableSvgOpt: TypeAlias = Annotated[bool, typer.Option("--table-svg", help="Output table as SVG")]
|
|
35
|
-
NumPartitionsOpt: TypeAlias = Annotated[Optional[int], typer.Option("-n", "--num-partitions", help="Number of output partitions")]
|
|
36
76
|
|
|
37
77
|
app = typer.Typer(
|
|
38
78
|
help="A CLI tool for viewing and manipulating tabular data.",
|
|
@@ -51,11 +91,12 @@ def main_callback(
|
|
|
51
91
|
] = False,
|
|
52
92
|
log_level: Annotated[
|
|
53
93
|
str,
|
|
54
|
-
typer.Option(
|
|
94
|
+
typer.Option(
|
|
95
|
+
"--log-level", help="Log level from {DEBUG, INFO, WARNING, ERROR, CRITICAL}"
|
|
96
|
+
),
|
|
55
97
|
] = "INFO",
|
|
56
98
|
) -> None:
|
|
57
99
|
"""Global options for tab_cli CLI."""
|
|
58
|
-
config.config.az_url_authority_is_account = az_url_authority_is_account
|
|
59
100
|
logger.remove()
|
|
60
101
|
logger.add(
|
|
61
102
|
RichHandler(
|
|
@@ -66,6 +107,10 @@ def main_callback(
|
|
|
66
107
|
format="{message}",
|
|
67
108
|
level=log_level.upper(),
|
|
68
109
|
)
|
|
110
|
+
load_config_file()
|
|
111
|
+
# CLI flags override config file values
|
|
112
|
+
if az_url_authority_is_account:
|
|
113
|
+
config.config.az_url_authority_is_account = az_url_authority_is_account
|
|
69
114
|
|
|
70
115
|
|
|
71
116
|
def _apply_sql(lf: pl.LazyFrame, sql: str | None) -> pl.LazyFrame:
|
|
@@ -94,21 +139,29 @@ def _transform_jmespath_batch(
|
|
|
94
139
|
if mode is None:
|
|
95
140
|
mode = "object"
|
|
96
141
|
elif mode != "object":
|
|
97
|
-
raise ValueError(
|
|
142
|
+
raise ValueError(
|
|
143
|
+
"JMESPath query must return a consistent shape across rows"
|
|
144
|
+
)
|
|
98
145
|
|
|
99
146
|
if expected_columns is not None:
|
|
100
147
|
extra_columns = set(result) - set(expected_columns)
|
|
101
148
|
if extra_columns:
|
|
102
149
|
extras = ", ".join(sorted(extra_columns))
|
|
103
|
-
raise ValueError(
|
|
104
|
-
|
|
150
|
+
raise ValueError(
|
|
151
|
+
f"JMESPath query produced unexpected columns: {extras}"
|
|
152
|
+
)
|
|
153
|
+
normalized_row = {
|
|
154
|
+
column: result.get(column) for column in expected_columns
|
|
155
|
+
}
|
|
105
156
|
else:
|
|
106
157
|
normalized_row = result
|
|
107
158
|
else:
|
|
108
159
|
if mode is None:
|
|
109
160
|
mode = "value"
|
|
110
161
|
elif mode != "value":
|
|
111
|
-
raise ValueError(
|
|
162
|
+
raise ValueError(
|
|
163
|
+
"JMESPath query must return a consistent shape across rows"
|
|
164
|
+
)
|
|
112
165
|
normalized_row = {"value": result}
|
|
113
166
|
|
|
114
167
|
rows.append(normalized_row)
|
|
@@ -143,10 +196,14 @@ def _apply_jmespath(lf: pl.LazyFrame, expression: str) -> pl.LazyFrame:
|
|
|
143
196
|
)
|
|
144
197
|
|
|
145
198
|
|
|
146
|
-
def _apply_query(
|
|
199
|
+
def _apply_query(
|
|
200
|
+
lf: pl.LazyFrame, sql: str | None, jmespath_expr: str | None
|
|
201
|
+
) -> pl.LazyFrame:
|
|
147
202
|
"""Apply exactly zero or one supported query transform to a LazyFrame."""
|
|
148
203
|
if sql is not None and jmespath_expr is not None:
|
|
149
|
-
raise ValueError(
|
|
204
|
+
raise ValueError(
|
|
205
|
+
"At most one query may be provided: use either --sql or --jmespath/--jp"
|
|
206
|
+
)
|
|
150
207
|
if sql is not None:
|
|
151
208
|
return _apply_sql(lf, sql)
|
|
152
209
|
if jmespath_expr is not None:
|
|
@@ -196,11 +253,18 @@ def view(
|
|
|
196
253
|
reader = infer_reader(path, format=input)
|
|
197
254
|
lf = reader.read(path)
|
|
198
255
|
lf = _apply_query(lf, sql=sql, jmespath_expr=jmespath_expr)
|
|
199
|
-
lf, truncated = _apply_limit(
|
|
200
|
-
|
|
256
|
+
lf, truncated = _apply_limit(
|
|
257
|
+
lf, limit=limit, skip=skip, default_limit=20 if limit is None else None
|
|
258
|
+
)
|
|
259
|
+
writer = infer_writer(
|
|
260
|
+
"table-svg" if table_svg else None,
|
|
261
|
+
truncated=truncated,
|
|
262
|
+
max_cell_len=max_cell_len,
|
|
263
|
+
)
|
|
201
264
|
for chunk in writer.write(lf):
|
|
202
265
|
sys.stdout.buffer.write(chunk)
|
|
203
266
|
|
|
267
|
+
|
|
204
268
|
@app.command()
|
|
205
269
|
def schema(
|
|
206
270
|
path: PathArg,
|
|
@@ -258,7 +322,9 @@ def convert(
|
|
|
258
322
|
elif input is not None:
|
|
259
323
|
writer = infer_writer(format=input)
|
|
260
324
|
else:
|
|
261
|
-
raise ValueError(
|
|
325
|
+
raise ValueError(
|
|
326
|
+
"Output format (-o/--output-format) is required when reading from stdin (-)"
|
|
327
|
+
)
|
|
262
328
|
assert isinstance(writer, TableWriter)
|
|
263
329
|
writer.write_to_path(lf, dst, partitions=num_partitions)
|
|
264
330
|
else:
|
|
@@ -305,7 +371,9 @@ def cat(
|
|
|
305
371
|
writer = infer_writer(format=input)
|
|
306
372
|
assert isinstance(writer, TableWriter)
|
|
307
373
|
else:
|
|
308
|
-
raise ValueError(
|
|
374
|
+
raise ValueError(
|
|
375
|
+
"Output format (-o/--output-format) or input format (-i/--input-format) is required when reading from stdin (-)"
|
|
376
|
+
)
|
|
309
377
|
for chunk in writer.write(lf):
|
|
310
378
|
sys.stdout.buffer.write(chunk)
|
|
311
379
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"""Global configuration for tab_cli-cli."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
from dataclasses import dataclass, fields
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from loguru import logger
|
|
8
|
+
|
|
9
|
+
CONFIG_DIR = Path.home() / ".config" / "tab"
|
|
10
|
+
CONFIG_FILE = CONFIG_DIR / "config.json"
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@dataclass
|
|
14
|
+
class Config:
|
|
15
|
+
"""Global configuration settings."""
|
|
16
|
+
|
|
17
|
+
az_url_authority_is_account: bool = False
|
|
18
|
+
sampling_size_for_schema_inference: int = 32
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
# Global config instance
|
|
22
|
+
config: Config = Config()
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def load_config_file(path: Path = CONFIG_FILE) -> None:
|
|
26
|
+
"""Load settings from a JSON config file into the global config.
|
|
27
|
+
|
|
28
|
+
Unknown keys are logged and ignored. Type mismatches raise ValueError.
|
|
29
|
+
If the file does not exist, this is a no-op.
|
|
30
|
+
"""
|
|
31
|
+
if not path.is_file():
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
text = path.read_text(encoding="utf-8")
|
|
35
|
+
data = json.loads(text)
|
|
36
|
+
if not isinstance(data, dict):
|
|
37
|
+
raise ValueError(
|
|
38
|
+
f"Config file must contain a JSON object, got {type(data).__name__}"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
known = {f.name: f.type for f in fields(Config)}
|
|
42
|
+
for key, value in data.items():
|
|
43
|
+
if key not in known:
|
|
44
|
+
logger.warning("Unknown config key '{}' in {}", key, path)
|
|
45
|
+
continue
|
|
46
|
+
setattr(config, key, value)
|
|
47
|
+
logger.debug("Loaded config from {}", path)
|
|
@@ -30,7 +30,7 @@ def _scan_parquet_with_pyarrow_fallback(
|
|
|
30
30
|
"Polars native Parquet reader failed ({}), retrying with PyArrow backend",
|
|
31
31
|
e,
|
|
32
32
|
)
|
|
33
|
-
return pl.
|
|
33
|
+
return pl.read_parquet(url, storage_options=storage_options, use_pyarrow=True).lazy()
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
class ParquetFormat(FormatHandler):
|