Merge remote-tracking branch 'origin/dev' into celery

This commit is contained in:
Gabriel Luiz Freitas Almeida 2023-09-22 14:50:19 -03:00
commit b3febf25dd
31 changed files with 582 additions and 263 deletions

View file

@ -56,3 +56,10 @@ LANGFLOW_REMOVE_API_KEYS=
# LANGFLOW_REDIS_CACHE_EXPIRE (default: 3600) # LANGFLOW_REDIS_CACHE_EXPIRE (default: 3600)
LANGFLOW_CACHE_TYPE= LANGFLOW_CACHE_TYPE=
# Superuser username
# Example: LANGFLOW_SUPERUSER=admin
LANGFLOW_SUPERUSER=
# Superuser password
# Example: LANGFLOW_SUPERUSER_PASSWORD=123456
LANGFLOW_SUPERUSER_PASSWORD=

View file

@ -19,6 +19,7 @@ coverage:
--cov-report term-missing:skip-covered --cov-report term-missing:skip-covered
tests: tests:
@make install_backend
poetry run pytest tests -n auto poetry run pytest tests -n auto
format: format:

138
poetry.lock generated
View file

@ -907,76 +907,76 @@ testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"]
[[package]] [[package]]
name = "clickhouse-connect" name = "clickhouse-connect"
version = "0.6.13" version = "0.6.14"
description = "ClickHouse Database Core Driver for Python, Pandas, and Superset" description = "ClickHouse Database Core Driver for Python, Pandas, and Superset"
optional = false optional = false
python-versions = "~=3.7" python-versions = "~=3.7"
files = [ files = [
{file = "clickhouse-connect-0.6.13.tar.gz", hash = "sha256:affec3369f486db1d17fc5447fef541a9a70df09c03e0ed4af6b328b6e6a4827"}, {file = "clickhouse-connect-0.6.14.tar.gz", hash = "sha256:0531bbd5b8bdee616bf1cca5ddcb0af86db12e2b48fd39257a8ecdf32200bd57"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3538dd61054af1d7af712f0203265969e351ca6e21a138c5cc967a4d63bc684"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:04affbd255fb8b1e4a882ddc1336c86530976d05578f47bb65e3a53471d291e4"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:08eac69a47c5d5bba727a475593662d5583a44a2168cb34c7e9727b0949edf05"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f5bd61f2665f1890fa632b1181df2900ea838cf152cd9a3f775841ea2deab680"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34cad54d3af842f98db7eda9a0fd4c0201383c6e6316b3db364a5e62957d3f92"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79897a0987008993f32737e17045a5c1982f9193f7511a3832a7ba3429cbf6b4"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9ecd833018ae61b1b5c23f1856e63112eb5a9240e30ae79e7cd63032bcc7683"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa95c8a96bdff593924407b074d616ee8a1bfb989579c17b330c6f3b27febfe3"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52cf7b75f4c9a215d1cde4bdab079b463f75edecf311a9f34248340de8c58ab8"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:501c0d843be30c86719b61089fb1de6298ac44b3670594f0a1cb0dc3ad97651e"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a5febb40a3220c2a3aaddaffe3cbc0c2c668dbf58d68875c5236551a43fb54f2"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1ec9672c9ed9d5e62f66ac14d6470b9b6be9946d6d24ddac87376437863b8f59"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:71072c28ef2d1d5c41f23b898014c8c491c54a745a13a545cd18e60d44d7276e"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:92173354a6c7c5862fab09dab338197b86a192e0c117137e899e8cf92cc3b5b7"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:47135049bacfdb67272df3e988458fc8cb3ca31df7fd020d7c28801272f319ae"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:757b4c05ebf10bdcb916334c3021ee571a61238907cdeee8c54bcf0550cd0d19"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-win32.whl", hash = "sha256:3ad88ca2b34d330513ac8e76f74dca4c1879a6ad81f6ef331e626400c3b9ff62"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-win32.whl", hash = "sha256:2e74badf6c7569e1a0ad32f3be250a3ebf28a9df3b15c9709104e5f050486016"},
{file = "clickhouse_connect-0.6.13-cp310-cp310-win_amd64.whl", hash = "sha256:092ddacb003a193f17ee3dbb6ac5df8397730154df95c668342e419e35dc42df"}, {file = "clickhouse_connect-0.6.14-cp310-cp310-win_amd64.whl", hash = "sha256:7b56c422467df5a0b2790e0943b747639f1f172fac7f8d9585adb3302c961fb1"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e77efffc06dede8ac479678420cc5e15b2be28b73119a458766047b964d31a36"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d2aa6d28d79eb5ca94d7c756ec4dc599d2354897f5ef40fd0d8bdc579a81dd94"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:39669fc21d1ab76fe6042511e424a00c7b5b731db2ff59c7a6222f15a65a77b0"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70cd5b2e0d80dc030355d09db213c73caa78ef259f2b04ce30c1c8cb513bf45b"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25005cf2c44bc46fa11b3e95de53830c172bf6f1cc512a2628bd62861b60777a"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:826c85e37555443af945a0d977598814ba7cb09447b0cdd167eae57dfd3f0724"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0d049b3c88466db6806d9b301436ddb69024df8cb1c14e5b21fab4517b67094"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cdb1f843d134a1e30828900bc51c9c1b4f4e638aac693767685e512fb095af5"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c329296469651124fb9787b6c060c22c05dfad1129f8e3683721cfe98b2b6574"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a8ea6ca6e0d6b1af50078413e280f271559c462a8644541002e44c2cb5c371"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9bb3a8f985626a8c5fc8d12e7e16e1f1774ef5c574faf10432e41a2e97ec2684"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:8b72a5e5d54069dff419a6ec9bbc7f3896fe558551cae6a2b2cba60eaa0607a3"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ed964a08ebd8ce4ddf44686efcf706fe6089a0b439813a4796c6cf3fc4f5ab11"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c531ed454ca9b6d85e739de3770a82eec2087ed2cb9660fb8ff0e62f7f1446cc"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9f4d3e17fa7c0b35e420450b18ad9fdde70f92635c12a69e5a18c699720c0442"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ae6ebf7c507f9d0fece9d1e387c9eec77762693f91647bca18f588cf1d594d24"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-win32.whl", hash = "sha256:fcab92aadd62ecc4dbe9f841c72e714f519f5251f45bf04f761504cd419abff3"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-win32.whl", hash = "sha256:cf1e3067c2da8525b6f59a37f8e13cd6c4524f439be8fd7d8fa03f007f96c863"},
{file = "clickhouse_connect-0.6.13-cp311-cp311-win_amd64.whl", hash = "sha256:a312939b94ec2dd49556cbef880804898fc14d5ca52aeb3d00b9905047ca64e0"}, {file = "clickhouse_connect-0.6.14-cp311-cp311-win_amd64.whl", hash = "sha256:15a040210877cc34155943c7870bf78247d4d4fa3bd4e0595ca22e97760679b7"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e3fef39ce56c5550ebc701fc439ca517eca10c57166216ebd37b664a5352be7"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eb91e4ee0435088fc8bd36de51a93ff9286a514d82ac373b57b2d6cad4655d77"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c1841a5f1c1298907c42e23fef1f4bdcdb6c7c40b2844469ccd4780e8f7cc16f"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48108bb1cfe99b6ff60344838859aec1315213dfa618f6ca4b92c0c6e5ae8d41"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:120618bf66df0908c0b8b5e8ea07c068d98032a9f498c832b1b02aa2cef91474"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c75d4bd8ef0b90f9e89ea70c16ff099278e4bb8f1e045008376ac34c6122b73d"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3a7c34efd02e68445cc6bf13f6de9c4b294112351e79a386cbd65c13fa08965"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:897f40eda84e9c45d0bdaf3a9e638e614e236a4a5eeab5cddd920857f9f8f22a"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a3f6a6975759b0b3aa8a4a6e05533bdce234a16804e69282bb0c01a5a37851a"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5ecc88656df05ae49e70062aee7022982eec3f87fb14db97c25276fef6633d7c"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6317a3ee357ce7129de18ce344792c545f4b28a190a47bf4047414c9b12dfaf2"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:76cec48265774ae3fa61a77b290dcc8385aad4312a8d7dfcaffb9fc00f79458e"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b0d07ae7b0d7ede51a336dfee5bbfdbf123957a50e9452d57f58b0c803517f21"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:dba280e00ec4cfe0e4d69f88baa9a0491bc1ed83ec57336e5197adae8d42d0c9"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-win32.whl", hash = "sha256:ef0ca69741762e512a6f1882d53bb1e607e2e04d24db995c8c0b3409943891b4"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-win32.whl", hash = "sha256:6c77f537e04747702e009c05f4a7f6f96cbe1696bb89d29f72e39e7370924836"},
{file = "clickhouse_connect-0.6.13-cp37-cp37m-win_amd64.whl", hash = "sha256:a5ba1ed57f4d8a47a87e353756746d4199527568b962931f5d6b9388ba72d8f3"}, {file = "clickhouse_connect-0.6.14-cp37-cp37m-win_amd64.whl", hash = "sha256:d0eceaff68a53f71384bb9aee7fc1630f68ac10538727c8516ae0af1103f2580"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:03f6738e9c737531d7ec67611cb476ca8b817b583e5f46349fc63b7357cdda4e"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9dfa09948caeed539cdd019a1e341a379a1dcacdd755b278d12484b4a703afa3"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:484b528d3c79f07f9c8a6586fb254578b8f8140a5a309820737f5017e9edd02e"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a30d99cb1fd57b8fed4449632e51d48386d0eec1673f905572c5fc7059215c20"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0c5589016da8a0a1c21d2461a98a6cab7c22633423735647632f5b5c0de7109"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e88de4fe66ae2b1c15726760cc87a703e4d1162de52a19c8d8b57a4429f08e"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81495c2d12a6420c1f3ee5d0cf3996329dbfd60e12e53905fd9da577b992c0c8"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03d721de610beae823068665d6c604a5f390a99e7b2354264b17136a3a520b13"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2239972b84dd33baf7cd552b53dec024716b87fbebb3a2ff741398a96fa15777"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a627762f2f692e226b3cb574a83133844213c6507c6313d3fefd8a3de08e5798"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9737310a7466f5ac10077ecbe10237e816a12a8cc4c651c2be82eaf25895042b"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:62a596f8d9db8592477a2032c329be7449ea32d133cdc4e5d6f804e251b8617a"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a229d67f1dec0351faf7634f523c8fcf78b602ee02b0e25c93f4d5018147d4f4"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:e8ab9e5a61968c328a0fdc254b02b96142ebb4ec2bc1623f9498538f0ebfdc7c"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a996fdf7d8e6bc18c9365fc06bd429418510cf63476a056e36afee505f570dad"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6c21fe379b1b8822eb9644600e38220b5c4b530fd0f2b1da824a0918120a8f01"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-win32.whl", hash = "sha256:56e51196caeb6b7f7b62af8e58ce1a653e29c694e4cf0964907ca7b42b32e7f0"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-win32.whl", hash = "sha256:2a17b336781d3fbb67ed556918c17e63c7d462709aa6a953bb3410ddb67fd7f4"},
{file = "clickhouse_connect-0.6.13-cp38-cp38-win_amd64.whl", hash = "sha256:a7b0cfec5eff21ec81f713de77a136d74f9336a20da5096b7a046b27ca1014b7"}, {file = "clickhouse_connect-0.6.14-cp38-cp38-win_amd64.whl", hash = "sha256:838a008c0f7d911ab81f741ea27a64ef7bdcc2508698b70f018987dfc742ffa9"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:909a6d4406a9320d85d7b71a131e68f9289ec66453ba7bf14e9a110db5f18e3d"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:083649a97c3f366f66f0f2578b9f88d86c1d3a40b9015c9403db524fda36a952"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7845ad20a8fba276dff1670c1bbedc3dc2c4d560fa486d8960fdd217b188099"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9e9bd6849852b2c55e51a477e10bc8b61990c5f37f31cce5ea6fc970b447b5af"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a9d5eb2036b740496a8d9f871cf928493fbc7d9edfc543e16f5db56ef359d468"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9152c45423f488cf6229bce1f9e695cd81e7ffcd3ae0f1e40e5e62079b18d4a5"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe0b889587bfe2962cbfe1b0a908f8bafee332a8f955f38fa307561dd73a962c"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:341e068d4a6a423ed22fb3b96cfe16be0d6305943c3fb1cc48251b7d9729931d"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f0414e6a2b2e19ad4165cb01503086d229473465217be86a7824cf9f4a2d3964"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ead7acb841524bd7a73b1f10592a36e901d63bc89af3270ab76b89a11d44fe20"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9065b9a7def6e1f7bf74e9c81825927f0b9147fcf1f0d172533552d931311279"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8bce432f72dcf6679c2d0bac4e3a82a126389ad7951d316f213109cee6925c7c"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2b7b4e29c781d8feb87cac6133ef8a20b59cd70e600d9f37875dd74384c8b792"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1f403499f169574cafb05888dfdaf18065cc49ff1321e5e108c504c8c220e172"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:66778f60bc66891ff375aa28447846a7f176743800f8fbec23001b05b8912020"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3189fcd339bfd7ae4e703ff40b110b9740d6b1ec8385ed8bd1547663fd046578"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-win32.whl", hash = "sha256:fa1f34d5b56f86417be2490e9cb22b1b27ff788e569636fdae1027d66816c2b3"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-win32.whl", hash = "sha256:a30de3f0997a9157e840c2d4e07fd9c6fc6e359f1ff9f3a46386b5abdca73c1a"},
{file = "clickhouse_connect-0.6.13-cp39-cp39-win_amd64.whl", hash = "sha256:b66574c7dc2a805071b582a66a0a46c92d3b3e1e897336cc32c5e0054204b401"}, {file = "clickhouse_connect-0.6.14-cp39-cp39-win_amd64.whl", hash = "sha256:c3476a95780374e94dfba2a28093d15f8370bfa6f4cb46a02e0af8813e5f7368"},
{file = "clickhouse_connect-0.6.13-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c87224b4ecec054395759cfbe5aab56f1728a14fb382178b0ae29c06068a1487"}, {file = "clickhouse_connect-0.6.14-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:22affe46983e67e3923e9330336d21e9ec4b4812b6fbeb1865514145b3870170"},
{file = "clickhouse_connect-0.6.13-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2f416e38cc935f982443a21642eac3d09e56f32fffa7a2ec90f36175bcd92ee"}, {file = "clickhouse_connect-0.6.14-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62727090af8875631115911f58442967386b31cd4efa93c951c2aa7e57d1ce4b"},
{file = "clickhouse_connect-0.6.13-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caffe66da4d9f8777b72ac93884ce7726a08a154527a444aa3e9913f4f44523f"}, {file = "clickhouse_connect-0.6.14-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee4ea5ac58de0580f2e12b46cfd2f8d13c1e690378bf9775bfed0c935232de71"},
{file = "clickhouse_connect-0.6.13-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdcb082acf5a1b754ea360e5df0f8805c17df1db9cdc47dcf10c7cfc2f0ea4d0"}, {file = "clickhouse_connect-0.6.14-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a126fe486dd02fa5f8adb0b9d8fd0fc701fb73b2275e1040ed210afadd189f90"},
{file = "clickhouse_connect-0.6.13-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:bebfd2d9fbaf67a84c78cce0f48cac3224c9eef62de7334e57dd32d38399bec9"}, {file = "clickhouse_connect-0.6.14-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:de6bf773c8776033ca5fb5a6a376729ae69afdd0b19a71d1460d1a221fc5a627"},
{file = "clickhouse_connect-0.6.13-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:98ef70b8e63f3145603a570bd479bc66f1269be18baec5df71c2f58959c345c1"}, {file = "clickhouse_connect-0.6.14-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d27d2c9698d1acb550ac8c30c4d9440c7d826a16444e4aea4dacf11ed7ec8988"},
{file = "clickhouse_connect-0.6.13-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd1ea8c2b694bb441371c7c964a9ff9b92489863087a306419fa8680ff189056"}, {file = "clickhouse_connect-0.6.14-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f57efbe536dfbfb7e10dd16ced6fe02441fb174450760f0b29b2b60d23c6462f"},
{file = "clickhouse_connect-0.6.13-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba59dead59a7f32522f502d3061fa70f0978b0a03ebe7992dcea53be4a5f587e"}, {file = "clickhouse_connect-0.6.14-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c134483da38a3d3e38c44da9f3d519d73e177998052d36129e21863c7a3497ee"},
{file = "clickhouse_connect-0.6.13-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c40ac936bb35bbf32aca6881755e392ba2ef3eece028e7b24c40498a662e9bfe"}, {file = "clickhouse_connect-0.6.14-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d6ae7ccb4ca3d310c2971ead9839935890e40da8602dcc92ecda9bbbb24366"},
{file = "clickhouse_connect-0.6.13-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:70397690dc7574d2ff546f311bd2243177925cc74f0df2613d2985a0da8c7516"}, {file = "clickhouse_connect-0.6.14-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0acf6b69b11b757d60545b0ccac3df4980f69351994e30074df84729bb5af5d1"},
{file = "clickhouse_connect-0.6.13-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d3ec25049fff943844e24a65112d15ed4d006f7c528362dd997844e4bcfce7cd"}, {file = "clickhouse_connect-0.6.14-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:e043b3b606749d23eca7601a1a44f188c6f117ae57a2852c66c21f11b7296fe4"},
{file = "clickhouse_connect-0.6.13-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b8614233a0ff7a3b469876b95dcf4557ed8fbc15c6997d49ddbde323537161"}, {file = "clickhouse_connect-0.6.14-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a887dfef3f3914454c7d7a428db8063b1678c66678cbabcd6368f0b67876f1"},
{file = "clickhouse_connect-0.6.13-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bf02bc20bf308853d6d382dac0d3347e4db2e76987610a098c7b1b207f355"}, {file = "clickhouse_connect-0.6.14-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e255e7c9c38fb9bceefc659374d04914ef2222a6f121fccf86a865b81110e96b"},
{file = "clickhouse_connect-0.6.13-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1ebd96561056f316ce129e9f7bdaa8043ee4c2f872903f36eff0920022487cba"}, {file = "clickhouse_connect-0.6.14-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2be9a6ba1d3055bb6956be218ffecfa3bfbe47121dfa34467815aa883f15d159"},
{file = "clickhouse_connect-0.6.13-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7de7099025a00954940dfe76f29ab529c5bece4ad8a2bc4131b7b8ff35ad60c8"}, {file = "clickhouse_connect-0.6.14-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:59faa034fdd58c1e7c8b2f4a033e9c611a0c58e193339cdd62d9d91a62f11195"},
] ]
[package.dependencies] [package.dependencies]
@ -3960,13 +3960,13 @@ files = [
[[package]] [[package]]
name = "metal-sdk" name = "metal-sdk"
version = "2.1.2" version = "2.1.3"
description = "SDK for getmetal.io" description = "SDK for getmetal.io"
optional = false optional = false
python-versions = ">=3.7" python-versions = ">=3.7"
files = [ files = [
{file = "metal_sdk-2.1.2-py3-none-any.whl", hash = "sha256:542ee620173994b43344779d8d9fc5540b06d4ac30941d824769f1e8bf767c0c"}, {file = "metal_sdk-2.1.3-py3-none-any.whl", hash = "sha256:c79f4ddb78b9ec83bb73969ce535ae33c601d34525088ee40268bc2ac5f69ba2"},
{file = "metal_sdk-2.1.2.tar.gz", hash = "sha256:a22895a5babd9c6bdd651ca4289f593ba5eee9742b97d12e6c5a859a3befef96"}, {file = "metal_sdk-2.1.3.tar.gz", hash = "sha256:43cb6244d7af5e1fe21b3d0fe59ee2e0f40d0350ea4779e80d9cf366d760407e"},
] ]
[package.dependencies] [package.dependencies]

View file

@ -360,8 +360,8 @@ def superuser(
# Verify that the superuser was created # Verify that the superuser was created
from langflow.services.database.models.user.user import User from langflow.services.database.models.user.user import User
user = session.query(User).filter(User.username == username).first() user: User = session.query(User).filter(User.username == username).first()
if user is None: if user is None or not user.is_superuser:
typer.echo("Superuser creation failed.") typer.echo("Superuser creation failed.")
return return

View file

@ -14,7 +14,7 @@ from langflow.services.database.models.api_key.crud import (
delete_api_key, delete_api_key,
) )
from langflow.services.database.models.user.user import User from langflow.services.database.models.user.user import User
from langflow.services.utils import get_session from langflow.services.getters import get_session
from sqlmodel import Session from sqlmodel import Session

View file

@ -13,9 +13,9 @@ from langflow.api.v1.schemas import BuildStatus, BuiltResponse, InitResponse, St
from langflow.graph.graph.base import Graph from langflow.graph.graph.base import Graph
from langflow.services.auth.utils import get_current_active_user, get_current_user from langflow.services.auth.utils import get_current_active_user, get_current_user
from langflow.services.utils import get_cache_service, get_session
from loguru import logger from loguru import logger
from langflow.services.utils import get_chat_service from langflow.services.getters import get_chat_service, get_session, get_cache_service
from cachetools import LRUCache
from sqlmodel import Session from sqlmodel import Session
from langflow.services.chat.manager import ChatService from langflow.services.chat.manager import ChatService
from langflow.services.cache.manager import BaseCacheService from langflow.services.cache.manager import BaseCacheService

View file

@ -2,7 +2,7 @@ from datetime import timezone
from typing import List from typing import List
from uuid import UUID from uuid import UUID
from langflow.services.database.models.component import Component, ComponentModel from langflow.services.database.models.component import Component, ComponentModel
from langflow.services.utils import get_session from langflow.services.getters import get_session
from sqlmodel import Session, select from sqlmodel import Session, select
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError

View file

@ -7,7 +7,7 @@ from langflow.services.cache.utils import save_uploaded_file
from langflow.services.database.models.flow import Flow from langflow.services.database.models.flow import Flow
from langflow.processing.process import process_graph_cached, process_tweaks from langflow.processing.process import process_graph_cached, process_tweaks
from langflow.services.database.models.user.user import User from langflow.services.database.models.user.user import User
from langflow.services.utils import get_settings_service, get_task_service from langflow.services.getters import get_settings_service, get_task_service
from loguru import logger from loguru import logger
from fastapi import APIRouter, Depends, HTTPException, UploadFile, Body, status from fastapi import APIRouter, Depends, HTTPException, UploadFile, Body, status
import sqlalchemy as sa import sqlalchemy as sa

View file

@ -2,7 +2,7 @@ from sqlmodel import Session
from fastapi import APIRouter, Depends, HTTPException, status from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.security import OAuth2PasswordRequestForm from fastapi.security import OAuth2PasswordRequestForm
from langflow.services.utils import get_session from langflow.services.getters import get_session
from langflow.api.v1.schemas import Token from langflow.api.v1.schemas import Token
from langflow.services.auth.utils import ( from langflow.services.auth.utils import (
authenticate_user, authenticate_user,

View file

@ -13,7 +13,7 @@ from sqlalchemy.exc import IntegrityError
from sqlmodel import Session, select from sqlmodel import Session, select
from fastapi import APIRouter, Depends, HTTPException from fastapi import APIRouter, Depends, HTTPException
from langflow.services.utils import get_session from langflow.services.getters import get_session
from langflow.services.auth.utils import ( from langflow.services.auth.utils import (
get_current_active_superuser, get_current_active_superuser,
get_current_active_user, get_current_active_user,

View file

@ -9,9 +9,11 @@ from langflow.api import router
from langflow.interface.utils import setup_llm_caching from langflow.interface.utils import setup_llm_caching
from langflow.services.database.utils import initialize_database from langflow.services.utils import initialize_services
from langflow.services.manager import initialize_services, teardown_services
from langflow.services.plugins.langfuse import LangfuseInstance from langflow.services.plugins.langfuse import LangfuseInstance
from langflow.services.utils import (
teardown_services,
)
from langflow.utils.logger import configure from langflow.utils.logger import configure
@ -39,11 +41,12 @@ def create_app():
app.include_router(router) app.include_router(router)
app.on_event("startup")(initialize_services) app.on_event("startup")(initialize_services)
app.on_event("startup")(initialize_database)
app.on_event("startup")(setup_llm_caching) app.on_event("startup")(setup_llm_caching)
app.on_event("shutdown")(teardown_services)
app.on_event("startup")(LangfuseInstance.update) app.on_event("startup")(LangfuseInstance.update)
app.on_event("shutdown")(teardown_services)
app.on_event("shutdown")(LangfuseInstance.teardown) app.on_event("shutdown")(LangfuseInstance.teardown)
return app return app

View file

@ -37,15 +37,13 @@ async def api_key_security(
result: Optional[Union[ApiKey, User]] = None result: Optional[Union[ApiKey, User]] = None
if settings_service.auth_settings.AUTO_LOGIN: if settings_service.auth_settings.AUTO_LOGIN:
# Get the first user # Get the first user
if not settings_service.auth_settings.FIRST_SUPERUSER: if not settings_manager.auth_settings.SUPERUSER:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,
detail="Missing first superuser credentials", detail="Missing first superuser credentials",
) )
result = get_user_by_username( result = get_user_by_username(db, settings_manager.auth_settings.SUPERUSER)
db, settings_service.auth_settings.FIRST_SUPERUSER
)
elif not query_param and not header_param: elif not query_param and not header_param:
raise HTTPException( raise HTTPException(
@ -181,9 +179,9 @@ def create_super_user(
def create_user_longterm_token(db: Session = Depends(get_session)) -> dict: def create_user_longterm_token(db: Session = Depends(get_session)) -> dict:
settings_service = get_settings_service() settings_manager = get_settings_service()
username = settings_service.auth_settings.FIRST_SUPERUSER username = settings_manager.auth_settings.SUPERUSER
password = settings_service.auth_settings.FIRST_SUPERUSER_PASSWORD password = settings_manager.auth_settings.SUPERUSER_PASSWORD
if not username or not password: if not username or not password:
raise HTTPException( raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST, status_code=status.HTTP_400_BAD_REQUEST,

View file

@ -3,6 +3,10 @@ from abc import ABC
class Service(ABC): class Service(ABC):
name: str name: str
ready: bool = False
def teardown(self): def teardown(self):
pass pass
def set_ready(self):
self.ready = True

View file

@ -164,10 +164,10 @@ class DatabaseService(Service):
try: try:
settings_service = get_settings_service() settings_service = get_settings_service()
# remove the default superuser if auto_login is enabled # remove the default superuser if auto_login is enabled
# using the FIRST_SUPERUSER to get the user # using the SUPERUSER to get the user
if settings_service.auth_settings.AUTO_LOGIN: if settings_service.auth_settings.AUTO_LOGIN:
logger.debug("Removing default superuser") logger.debug("Removing default superuser")
username = settings_service.auth_settings.FIRST_SUPERUSER username = settings_service.auth_settings.SUPERUSER
with Session(self.engine) as session: with Session(self.engine) as session:
user = get_user_by_username(session, username) user = get_user_by_username(session, username)
session.delete(user) session.delete(user)

View file

@ -3,7 +3,7 @@ from typing import Union
from uuid import UUID from uuid import UUID
from fastapi import Depends, HTTPException, status from fastapi import Depends, HTTPException, status
from langflow.services.database.models.user.user import User, UserUpdate from langflow.services.database.models.user.user import User, UserUpdate
from langflow.services.utils import get_session from langflow.services.getters import get_session
from sqlalchemy.exc import IntegrityError from sqlalchemy.exc import IntegrityError
from sqlmodel import Session from sqlmodel import Session
from typing import Optional from typing import Optional

View file

@ -0,0 +1,26 @@
from langflow.services import ServiceType, service_manager
from typing import TYPE_CHECKING, Generator
if TYPE_CHECKING:
from langflow.services.database.manager import DatabaseManager
from langflow.services.settings.manager import SettingsManager
from langflow.services.chat.manager import ChatManager
from sqlmodel import Session
def get_settings_manager() -> "SettingsManager":
return service_manager.get(ServiceType.SETTINGS_MANAGER)
def get_db_manager() -> "DatabaseManager":
return service_manager.get(ServiceType.DATABASE_MANAGER)
def get_session() -> Generator["Session", None, None]:
db_manager = service_manager.get(ServiceType.DATABASE_MANAGER)
yield from db_manager.get_session()
def get_chat_manager() -> "ChatManager":
return service_manager.get(ServiceType.CHAT_MANAGER)

View file

@ -62,6 +62,7 @@ class ServiceManager:
self.services[service_name] = self.factories[service_name].create( self.services[service_name] = self.factories[service_name].create(
**dependent_services **dependent_services
) )
self.services[service_name].set_ready()
def _validate_service_creation(self, service_name: ServiceType): def _validate_service_creation(self, service_name: ServiceType):
""" """
@ -113,34 +114,34 @@ def initialize_services():
service_manager.register_factory(settings_factory.SettingsServiceFactory()) service_manager.register_factory(settings_factory.SettingsServiceFactory())
service_manager.register_factory( service_manager.register_factory(
database_factory.DatabaseServiceFactory(), database_factory.DatabaseServiceFactory(),
dependencies=[ServiceType.SETTINGS_MANAGER], dependencies=[ServiceType.SETTINGS_SERVICE],
) )
service_manager.register_factory( service_manager.register_factory(
cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_MANAGER] cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_SERVICE]
) )
service_manager.register_factory( service_manager.register_factory(
auth_factory.AuthServiceFactory(), dependencies=[ServiceType.SETTINGS_MANAGER] auth_factory.AuthServiceFactory(), dependencies=[ServiceType.SETTINGS_SERVICE]
) )
service_manager.register_factory(chat_factory.ChatServiceFactory()) service_manager.register_factory(chat_factory.ChatServiceFactory())
service_manager.register_factory( service_manager.register_factory(
session_service_factory.SessionServiceFactory(), session_service_factory.SessionServiceFactory(),
dependencies=[ServiceType.CACHE_MANAGER], dependencies=[ServiceType.CACHE_SERVICE],
) )
service_manager.register_factory( service_manager.register_factory(
task_factory.TaskServiceFactory(), task_factory.TaskServiceFactory(),
) )
# Test cache connection # Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER) service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection # Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER) service_manager.get(ServiceType.DATABASE_SERVICE)
# Test cache connection # Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER) service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection # Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER) service_manager.get(ServiceType.DATABASE_SERVICE)
def reinitialize_services(): def reinitialize_services():
@ -155,23 +156,23 @@ def reinitialize_services():
from langflow.services.auth import factory as auth_factory from langflow.services.auth import factory as auth_factory
from langflow.services.task import factory as task_factory from langflow.services.task import factory as task_factory
service_manager.update(ServiceType.SETTINGS_MANAGER) service_manager.update(ServiceType.SETTINGS_SERVICE)
service_manager.update(ServiceType.DATABASE_MANAGER) service_manager.update(ServiceType.DATABASE_SERVICE)
service_manager.update(ServiceType.CACHE_MANAGER) service_manager.update(ServiceType.CACHE_SERVICE)
service_manager.update(ServiceType.CHAT_MANAGER) service_manager.update(ServiceType.CHAT_SERVICE)
service_manager.update(ServiceType.SESSION_MANAGER) service_manager.update(ServiceType.SESSION_SERVICE)
service_manager.update(ServiceType.AUTH_MANAGER) service_manager.update(ServiceType.AUTH_SERVICE)
service_manager.update(ServiceType.TASK_MANAGER) service_manager.update(ServiceType.TASK_SERVICE)
# Test cache connection # Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER) service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection # Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER) service_manager.get(ServiceType.DATABASE_SERVICE)
# Test cache connection # Test cache connection
service_manager.get(ServiceType.CACHE_MANAGER) service_manager.get(ServiceType.CACHE_SERVICE)
# Test database connection # Test database connection
service_manager.get(ServiceType.DATABASE_MANAGER) service_manager.get(ServiceType.DATABASE_SERVICE)
def initialize_settings_service(): def initialize_settings_service():
@ -193,12 +194,12 @@ def initialize_session_service():
initialize_settings_service() initialize_settings_service()
service_manager.register_factory( service_manager.register_factory(
cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_MANAGER] cache_factory.CacheServiceFactory(), dependencies=[ServiceType.SETTINGS_SERVICE]
) )
service_manager.register_factory( service_manager.register_factory(
session_service_factory.SessionServiceFactory(), session_service_factory.SessionServiceFactory(),
dependencies=[ServiceType.CACHE_MANAGER], dependencies=[ServiceType.CACHE_SERVICE],
) )

View file

@ -1,6 +1,10 @@
from pathlib import Path from pathlib import Path
from typing import Optional from typing import Optional
import secrets import secrets
from langflow.services.settings.constants import (
DEFAULT_SUPERUSER,
DEFAULT_SUPERUSER_PASSWORD,
)
from langflow.services.settings.utils import read_secret_from_file, write_secret_to_file from langflow.services.settings.utils import read_secret_from_file, write_secret_to_file
from pydantic import BaseSettings, Field, validator from pydantic import BaseSettings, Field, validator
@ -30,9 +34,9 @@ class AuthSettings(BaseSettings):
# If AUTO_LOGIN = True # If AUTO_LOGIN = True
# > The application does not request login and logs in automatically as a super user. # > The application does not request login and logs in automatically as a super user.
AUTO_LOGIN: bool = True AUTO_LOGIN: bool = False
FIRST_SUPERUSER: str = "langflow" SUPERUSER: str = DEFAULT_SUPERUSER
FIRST_SUPERUSER_PASSWORD: str = "langflow" SUPERUSER_PASSWORD: str = DEFAULT_SUPERUSER_PASSWORD
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto") pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
@ -41,6 +45,28 @@ class AuthSettings(BaseSettings):
extra = "ignore" extra = "ignore"
env_prefix = "LANGFLOW_" env_prefix = "LANGFLOW_"
def reset_credentials(self):
self.SUPERUSER = DEFAULT_SUPERUSER
self.SUPERUSER_PASSWORD = DEFAULT_SUPERUSER_PASSWORD
# If autologin is true, then we need to set the credentials to
# the default values
# so we need to validate the superuser and superuser_password
# fields
@validator("SUPERUSER", "SUPERUSER_PASSWORD", pre=True)
def validate_superuser(cls, value, values):
if values.get("AUTO_LOGIN"):
if value != DEFAULT_SUPERUSER:
value = DEFAULT_SUPERUSER
logger.debug("Resetting superuser to default value")
if values.get("SUPERUSER_PASSWORD") != DEFAULT_SUPERUSER_PASSWORD:
values["SUPERUSER_PASSWORD"] = DEFAULT_SUPERUSER_PASSWORD
logger.debug("Resetting superuser password to default value")
return value
return value
@validator("SECRET_KEY", pre=True) @validator("SECRET_KEY", pre=True)
def get_secret_key(cls, value, values): def get_secret_key(cls, value, values):
config_dir = values.get("CONFIG_DIR") config_dir = values.get("CONFIG_DIR")

View file

@ -0,0 +1,2 @@
DEFAULT_SUPERUSER = "langflow"
DEFAULT_SUPERUSER_PASSWORD = "langflow"

View file

@ -1,48 +1,143 @@
from langflow.services import ServiceType, service_manager from langflow.services.auth.utils import create_super_user
from typing import TYPE_CHECKING, Generator from langflow.services.database.utils import initialize_database
from langflow.services.manager import service_manager
from langflow.services.schema import ServiceType
from langflow.services.settings.constants import (
DEFAULT_SUPERUSER,
DEFAULT_SUPERUSER_PASSWORD,
)
from .getters import get_session, get_settings_service
from loguru import logger
if TYPE_CHECKING: def setup_superuser():
from langflow.services.database.manager import DatabaseService """
from langflow.services.settings.manager import SettingsService Setup the superuser.
from langflow.services.cache.manager import BaseCacheService """
from langflow.services.session.manager import SessionService # We will use the SUPERUSER and SUPERUSER_PASSWORD
from langflow.services.task.manager import TaskService # vars on settings_manager.auth_settings to create the superuser
from langflow.services.chat.manager import ChatService # if it does not exist.
from sqlmodel import Session settings_manager = get_settings_service()
if settings_manager.auth_settings.AUTO_LOGIN:
logger.debug("AUTO_LOGIN is set to True. Creating default superuser.")
session = next(get_session())
username = settings_manager.auth_settings.SUPERUSER
password = settings_manager.auth_settings.SUPERUSER_PASSWORD
if username == DEFAULT_SUPERUSER and password == DEFAULT_SUPERUSER_PASSWORD:
logger.debug("Default superuser credentials detected.")
logger.debug("Creating default superuser.")
else:
logger.debug("Creating superuser.")
def get_settings_service() -> "SettingsService":
try: try:
return service_manager.get(ServiceType.SETTINGS_MANAGER) from langflow.services.database.models.user.user import User
except ValueError:
# initialize settings service
from langflow.services.manager import initialize_settings_service
initialize_settings_service() user = session.query(User).filter(User.username == username).first()
return service_manager.get(ServiceType.SETTINGS_MANAGER) if user and user.is_superuser is True:
return
except Exception as exc:
logger.exception(exc)
raise RuntimeError(
"Could not create superuser. Please create a superuser manually."
) from exc
try:
# create superuser
create_super_user(db=session, username=username, password=password)
except Exception as exc:
logger.exception(exc)
raise RuntimeError(
"Could not create superuser. Please create a superuser manually."
) from exc
# reset superuser credentials
settings_manager.auth_settings.reset_credentials()
logger.debug("Superuser created successfully.")
def get_db_service() -> "DatabaseService": def teardown_superuser():
return service_manager.get(ServiceType.DATABASE_MANAGER) """
Teardown the superuser.
"""
# If AUTO_LOGIN is True, we will remove the default superuser
# from the database.
settings_manager = get_settings_service()
if settings_manager.auth_settings.AUTO_LOGIN:
logger.debug("AUTO_LOGIN is set to True. Removing default superuser.")
session = next(get_session())
username = settings_manager.auth_settings.SUPERUSER
from langflow.services.database.models.user.user import User
user = session.query(User).filter(User.username == username).first()
if user and user.is_superuser:
session.delete(user)
session.commit()
logger.debug("Default superuser removed successfully.")
else:
logger.debug("Default superuser not found.")
def get_session() -> Generator["Session", None, None]: def teardown_services():
db_service = service_manager.get(ServiceType.DATABASE_MANAGER) """
yield from db_service.get_session() Teardown all the services.
"""
teardown_superuser()
service_manager.teardown()
def get_cache_service() -> "BaseCacheService": def initialize_settings_manager():
return service_manager.get(ServiceType.CACHE_MANAGER) """
Initialize the settings manager.
"""
from langflow.services.settings import factory as settings_factory
service_manager.register_factory(settings_factory.SettingsManagerFactory())
def get_session_service() -> "SessionService": def initialize_session_manager():
return service_manager.get(ServiceType.SESSION_MANAGER) """
Initialize the session manager.
"""
from langflow.services.session import factory as session_manager_factory # type: ignore
from langflow.services.cache import factory as cache_factory
initialize_settings_manager()
service_manager.register_factory(
cache_factory.CacheManagerFactory(), dependencies=[ServiceType.SETTINGS_MANAGER]
)
service_manager.register_factory(
session_manager_factory.SessionManagerFactory(),
dependencies=[ServiceType.CACHE_MANAGER],
)
def get_task_service() -> "TaskService": def initialize_services():
return service_manager.get(ServiceType.TASK_MANAGER) """
Initialize all the services needed.
"""
from langflow.services.database import factory as database_factory
from langflow.services.cache import factory as cache_factory
from langflow.services.chat import factory as chat_factory
from langflow.services.settings import factory as settings_factory
from langflow.services.auth import factory as auth_factory
service_manager.register_factory(settings_factory.SettingsManagerFactory())
service_manager.register_factory(
auth_factory.AuthManagerFactory(), dependencies=[ServiceType.SETTINGS_MANAGER]
)
service_manager.register_factory(
database_factory.DatabaseManagerFactory(),
dependencies=[ServiceType.SETTINGS_MANAGER],
)
service_manager.register_factory(cache_factory.CacheManagerFactory())
service_manager.register_factory(chat_factory.ChatManagerFactory())
def get_chat_service() -> "ChatService": # Test cache connection
return service_manager.get(ServiceType.CHAT_MANAGER) service_manager.get(ServiceType.CACHE_MANAGER)
# Test database connection
db_manager = service_manager.get(ServiceType.DATABASE_MANAGER)
# Setup the superuser
initialize_database()
if db_manager.ready:
setup_superuser()

View file

@ -36,15 +36,16 @@ export const EditFlowSettings: React.FC<InputProps> = ({
} }
if (invalidName !== undefined) { if (invalidName !== undefined) {
if (!nameLists.current.includes(value)) { if (!nameLists.current.includes(value)) {
setInvalidName(false); setInvalidName!(false);
} else { } else {
setInvalidName(true); setInvalidName!(true);
}
if (!nameLists.current.includes(value)) {
setInvalidName!(false);
} else {
setInvalidName!(true);
} }
}
if (!nameLists.current.includes(value)) {
setInvalidName!(false);
} else {
setInvalidName!(true);
} }
setName(value); setName(value);
}; };

View file

@ -2,13 +2,14 @@ from contextlib import contextmanager
import json import json
from pathlib import Path from pathlib import Path
from typing import AsyncGenerator, TYPE_CHECKING from typing import AsyncGenerator, TYPE_CHECKING
from langflow.api.v1.flows import get_session
from langflow.graph.graph.base import Graph from langflow.graph.graph.base import Graph
from langflow.services.auth.utils import get_password_hash from langflow.services.auth.utils import get_password_hash
from langflow.services.database.models.flow.flow import Flow, FlowCreate from langflow.services.database.models.flow.flow import Flow, FlowCreate
from langflow.services.database.models.user.user import User, UserCreate from langflow.services.database.models.user.user import User, UserCreate
import orjson import orjson
from langflow.services.database.utils import session_getter
from langflow.services.getters import get_db_manager
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from httpx import AsyncClient from httpx import AsyncClient
@ -16,6 +17,9 @@ from sqlmodel import SQLModel, Session, create_engine
from sqlmodel.pool import StaticPool from sqlmodel.pool import StaticPool
from typer.testing import CliRunner from typer.testing import CliRunner
# we need to import tmpdir
import tempfile
if TYPE_CHECKING: if TYPE_CHECKING:
from langflow.services.database.manager import DatabaseService from langflow.services.database.manager import DatabaseService
@ -61,22 +65,6 @@ def session_fixture():
yield session yield session
@pytest.fixture(name="client")
def client_fixture(session: Session, monkeypatch):
def get_session_override():
return session
monkeypatch.setenv("LANGFLOW_AUTO_LOGIN", False)
from langflow.main import create_app
app = create_app()
app.dependency_overrides[get_session] = get_session_override
with TestClient(app) as client:
yield client
app.dependency_overrides.clear()
class Config: class Config:
broker_url = "redis://localhost:6379/0" broker_url = "redis://localhost:6379/0"
result_backend = "redis://localhost:6379/0" result_backend = "redis://localhost:6379/0"
@ -182,27 +170,33 @@ def json_vector_store():
return f.read() return f.read()
# @contextmanager @pytest.fixture(name="client", autouse=True)
# def session_getter(): def client_fixture(session: Session, monkeypatch):
# try: # Set the database url to a test database
# session = Session(engine) db_dir = tempfile.mkdtemp()
# yield session db_path = Path(db_dir) / "test.db"
# except Exception as e: monkeypatch.setenv("LANGFLOW_DATABASE_URL", f"sqlite:///{db_path}")
# print("Session rollback because of exception:", e) monkeypatch.setenv("LANGFLOW_AUTO_LOGIN", False)
# session.rollback()
# raise def get_session_override():
# finally: return session
# session.close()
from langflow.main import create_app
app = create_app()
# app.dependency_overrides[get_session] = get_session_override
with TestClient(app) as client:
yield client
# app.dependency_overrides.clear()
monkeypatch.undo()
# clear the temp db
db_path.unlink()
# create a fixture for session_getter above # create a fixture for session_getter above
@pytest.fixture(name="session_getter") @pytest.fixture(name="session_getter")
def session_getter_fixture(client): def session_getter_fixture(client):
engine = create_engine(
"sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool
)
SQLModel.metadata.create_all(engine)
@contextmanager @contextmanager
def blank_session_getter(db_service: "DatabaseService"): def blank_session_getter(db_service: "DatabaseService"):
with Session(db_service.engine) as session: with Session(db_service.engine) as session:
@ -228,17 +222,18 @@ def test_user(client):
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def active_user(client, session): def active_user(client):
user = User( db_manager = get_db_manager()
username="activeuser", with session_getter(db_manager) as session:
password=get_password_hash( user = User(
"testpassword" username="activeuser",
), # Assuming password needs to be hashed password=get_password_hash("testpassword"),
is_active=True, is_active=True,
is_superuser=False, is_superuser=False,
) )
session.add(user) session.add(user)
session.commit() session.commit()
session.refresh(user)
return user return user
@ -253,7 +248,7 @@ def logged_in_headers(client, active_user):
@pytest.fixture @pytest.fixture
def flow(client, json_flow: str, session, active_user): def flow(client, json_flow: str, active_user):
from langflow.services.database.models.flow.flow import FlowCreate from langflow.services.database.models.flow.flow import FlowCreate
loaded_json = json.loads(json_flow) loaded_json = json.loads(json_flow)
@ -261,8 +256,10 @@ def flow(client, json_flow: str, session, active_user):
name="test_flow", data=loaded_json.get("data"), user_id=active_user.id name="test_flow", data=loaded_json.get("data"), user_id=active_user.id
) )
flow = Flow(**flow_data.dict()) flow = Flow(**flow_data.dict())
session.add(flow) with session_getter(get_db_manager()) as session:
session.commit() session.add(flow)
session.commit()
session.refresh(flow)
return flow return flow

View file

@ -3,7 +3,7 @@ from tempfile import tempdir
from langflow.__main__ import app from langflow.__main__ import app
import pytest import pytest
from langflow.services import utils from langflow.services import getters
@pytest.fixture(scope="module") @pytest.fixture(scope="module")
@ -26,7 +26,7 @@ def test_components_path(runner, client, default_settings):
["run", "--components-path", str(temp_dir), *default_settings], ["run", "--components-path", str(temp_dir), *default_settings],
) )
assert result.exit_code == 0, result.stdout assert result.exit_code == 0, result.stdout
settings_service = utils.get_settings_service() settings_service = getters.get_settings_service()
assert str(temp_dir) in settings_service.settings.COMPONENTS_PATH assert str(temp_dir) in settings_service.settings.COMPONENTS_PATH

View file

@ -518,13 +518,13 @@ def db(app):
app.db.drop_all() app.db.drop_all()
def test_list_flows_return_type(component, session_getter): def test_list_flows_return_type(component):
flows = component.list_flows(get_session=session_getter) flows = component.list_flows()
assert isinstance(flows, list) assert isinstance(flows, list)
def test_list_flows_flow_objects(component, session_getter): def test_list_flows_flow_objects(component):
flows = component.list_flows(get_session=session_getter) flows = component.list_flows()
assert all(isinstance(flow, Flow) for flow in flows) assert all(isinstance(flow, Flow) for flow in flows)

View file

@ -1,4 +1,6 @@
from langflow.services.database.models.base import orjson_dumps from langflow.services.database.models.base import orjson_dumps
from langflow.services.database.utils import session_getter
from langflow.services.getters import get_db_manager
import orjson import orjson
import pytest import pytest
@ -194,18 +196,20 @@ def test_download_file(
FlowCreate(name="Flow 2", description="description", data=data), FlowCreate(name="Flow 2", description="description", data=data),
] ]
) )
for flow in flow_list.flows: db_manager = get_db_manager()
flow.user_id = active_user.id with session_getter(db_manager) as session:
db_flow = Flow.from_orm(flow) for flow in flow_list.flows:
session.add(db_flow) flow.user_id = active_user.id
session.commit() db_flow = Flow.from_orm(flow)
session.add(db_flow)
session.commit()
# Make request to endpoint # Make request to endpoint
response = client.get("api/v1/flows/download/", headers=logged_in_headers) response = client.get("api/v1/flows/download/", headers=logged_in_headers)
# Check response status code # Check response status code
assert response.status_code == 200 assert response.status_code == 200, response.json()
# Check response data # Check response data
response_data = response.json()["flows"] response_data = response.json()["flows"]
assert len(response_data) == 2 assert len(response_data) == 2, response_data
assert response_data[0]["name"] == "Flow 1" assert response_data[0]["name"] == "Flow 1"
assert response_data[0]["description"] == "description" assert response_data[0]["description"] == "description"
assert response_data[0]["data"] == data assert response_data[0]["data"] == data

View file

@ -2,7 +2,9 @@ import uuid
from langflow.processing.process import Result from langflow.processing.process import Result
from langflow.services.auth.utils import get_password_hash from langflow.services.auth.utils import get_password_hash
from langflow.services.database.models.api_key.api_key import ApiKey from langflow.services.database.models.api_key.api_key import ApiKey
from langflow.services.utils import get_settings_service from langflow.services.getters import get_settings_service
from langflow.services.database.utils import session_getter
from langflow.services.getters import get_db_manager
import pytest import pytest
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from langflow.interface.tools.constants import CUSTOM_TOOLS from langflow.interface.tools.constants import CUSTOM_TOOLS
@ -117,7 +119,7 @@ PROMPT_REQUEST = {
@pytest.fixture @pytest.fixture
def created_api_key(session, active_user): def created_api_key(active_user):
hashed = get_password_hash("random_key") hashed = get_password_hash("random_key")
api_key = ApiKey( api_key = ApiKey(
name="test_api_key", name="test_api_key",
@ -125,10 +127,11 @@ def created_api_key(session, active_user):
api_key="random_key", api_key="random_key",
hashed_api_key=hashed, hashed_api_key=hashed,
) )
db_manager = get_db_manager()
session.add(api_key) with session_getter(db_manager) as session:
session.commit() session.add(api_key)
session.refresh(api_key) session.commit()
session.refresh(api_key)
return api_key return api_key

View file

@ -1,3 +1,5 @@
from langflow.services.database.utils import session_getter
from langflow.services.getters import get_db_manager
import pytest import pytest
from langflow.services.database.models.user import User from langflow.services.database.models.user import User
from langflow.services.auth.utils import get_password_hash from langflow.services.auth.utils import get_password_hash
@ -15,10 +17,11 @@ def test_user():
) )
def test_login_successful(client, test_user, session): def test_login_successful(client, test_user):
# Adding the test user to the database # Adding the test user to the database
session.add(test_user) with session_getter(get_db_manager()) as session:
session.commit() session.add(test_user)
session.commit()
response = client.post( response = client.post(
"api/v1/login", data={"username": "testuser", "password": "testpassword"} "api/v1/login", data={"username": "testuser", "password": "testpassword"}

View file

@ -1,5 +1,5 @@
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from langflow.services.utils import get_settings_service from langflow.services.getters import get_settings_service
def test_prompts_settings(client: TestClient, logged_in_headers): def test_prompts_settings(client: TestClient, logged_in_headers):

View file

@ -0,0 +1,140 @@
from unittest.mock import patch, Mock, MagicMock, call
from langflow.services.database.models.user.user import User
from langflow.services.settings.constants import (
DEFAULT_SUPERUSER,
DEFAULT_SUPERUSER_PASSWORD,
)
from langflow.services.utils import setup_superuser, teardown_superuser
@patch("langflow.services.utils.get_settings_manager")
@patch("langflow.services.utils.create_super_user")
@patch("langflow.services.utils.get_session")
def test_setup_superuser(
mock_get_session, mock_create_super_user, mock_get_settings_manager
):
# Test when AUTO_LOGIN is True
calls = []
mock_settings_manager = Mock()
mock_settings_manager.auth_settings.AUTO_LOGIN = True
mock_settings_manager.auth_settings.SUPERUSER = DEFAULT_SUPERUSER
mock_settings_manager.auth_settings.SUPERUSER_PASSWORD = DEFAULT_SUPERUSER_PASSWORD
mock_get_settings_manager.return_value = mock_settings_manager
mock_session = Mock()
mock_session.query.return_value.filter.return_value.first.return_value = (
mock_session
)
# return value of get_session is a generator
mock_get_session.return_value = iter([mock_session, mock_session, mock_session])
setup_superuser()
mock_session.query.assert_called_once_with(User)
actual_expr = mock_session.query.return_value.filter.call_args[0][0]
expected_expr = User.username == DEFAULT_SUPERUSER
assert str(actual_expr) == str(expected_expr)
create_call = call(
db=mock_session, username=DEFAULT_SUPERUSER, password=DEFAULT_SUPERUSER_PASSWORD
)
calls.append(create_call)
mock_create_super_user.assert_has_calls(calls)
assert 1 == mock_create_super_user.call_count
def reset_mock_credentials():
mock_settings_manager.auth_settings.SUPERUSER = DEFAULT_SUPERUSER
mock_settings_manager.auth_settings.SUPERUSER_PASSWORD = (
DEFAULT_SUPERUSER_PASSWORD
)
ADMIN_USER_NAME = "admin_user"
# Test when username and password are default
mock_settings_manager.auth_settings = Mock()
mock_settings_manager.auth_settings.AUTO_LOGIN = False
mock_settings_manager.auth_settings.SUPERUSER = ADMIN_USER_NAME
mock_settings_manager.auth_settings.SUPERUSER_PASSWORD = "password"
mock_settings_manager.auth_settings.reset_credentials = Mock(
side_effect=reset_mock_credentials
)
mock_get_settings_manager.return_value = mock_settings_manager
setup_superuser()
mock_session.query.assert_called_with(User)
actual_expr = mock_session.query.return_value.filter.call_args[0][0]
expected_expr = User.username == ADMIN_USER_NAME
assert str(actual_expr) == str(expected_expr)
create_call = call(db=mock_session, username=ADMIN_USER_NAME, password="password")
calls.append(create_call)
mock_create_super_user.assert_has_calls(calls)
assert 2 == mock_create_super_user.call_count
# Test that superuser credentials are reset
mock_settings_manager.auth_settings.reset_credentials.assert_called_once()
assert mock_settings_manager.auth_settings.SUPERUSER != ADMIN_USER_NAME
assert mock_settings_manager.auth_settings.SUPERUSER_PASSWORD != "password"
# Test when superuser already exists
mock_settings_manager.auth_settings.AUTO_LOGIN = False
mock_settings_manager.auth_settings.SUPERUSER = ADMIN_USER_NAME
mock_settings_manager.auth_settings.SUPERUSER_PASSWORD = "password"
mock_user = Mock()
mock_user.is_superuser = True
mock_session.query.return_value.filter.return_value.first.return_value = mock_user
setup_superuser()
mock_session.query.assert_called_with(User)
actual_expr = mock_session.query.return_value.filter.call_args[0][0]
expected_expr = User.username == ADMIN_USER_NAME
assert str(actual_expr) == str(expected_expr)
@patch("langflow.services.utils.get_settings_manager")
@patch("langflow.services.utils.get_session")
def test_teardown_superuser_default_superuser(
mock_get_session, mock_get_settings_manager
):
mock_settings_manager = MagicMock()
mock_settings_manager.auth_settings.AUTO_LOGIN = True
mock_settings_manager.auth_settings.SUPERUSER = DEFAULT_SUPERUSER
mock_settings_manager.auth_settings.SUPERUSER_PASSWORD = DEFAULT_SUPERUSER_PASSWORD
mock_get_settings_manager.return_value = mock_settings_manager
mock_session = MagicMock()
mock_user = MagicMock()
mock_user.is_superuser = True
mock_session.query.return_value.filter.return_value.first.return_value = mock_user
mock_get_session.return_value = iter([mock_session])
teardown_superuser()
mock_session.query.assert_called_once_with(User)
actual_expr = mock_session.query.return_value.filter.call_args[0][0]
expected_expr = User.username == DEFAULT_SUPERUSER
assert str(actual_expr) == str(expected_expr)
mock_session.delete.assert_called_once_with(mock_user)
mock_session.commit.assert_called_once()
@patch("langflow.services.utils.get_settings_manager")
@patch("langflow.services.utils.get_session")
def test_teardown_superuser_no_default_superuser(
mock_get_session, mock_get_settings_manager
):
ADMIN_USER_NAME = "admin_user"
mock_settings_manager = MagicMock()
mock_settings_manager.auth_settings.AUTO_LOGIN = False
mock_settings_manager.auth_settings.SUPERUSER = ADMIN_USER_NAME
mock_settings_manager.auth_settings.SUPERUSER_PASSWORD = "password"
mock_get_settings_manager.return_value = mock_settings_manager
mock_session = MagicMock()
mock_user = MagicMock()
mock_user.is_superuser = False
mock_session.query.return_value.filter.return_value.first.return_value = mock_user
mock_get_session.return_value = [mock_session]
teardown_superuser()
mock_session.query.assert_not_called()
mock_session.delete.assert_not_called()
mock_session.commit.assert_not_called()

View file

@ -2,20 +2,22 @@ from datetime import datetime
from langflow.services.auth.utils import create_super_user, get_password_hash from langflow.services.auth.utils import create_super_user, get_password_hash
from langflow.services.database.models.user.user import User from langflow.services.database.models.user.user import User
from langflow.services.utils import get_settings_service from langflow.services.database.utils import session_getter
from langflow.services.getters import get_db_service, get_settings_service
import pytest import pytest
from langflow.services.database.models.user import UserUpdate from langflow.services.database.models.user import UserUpdate
@pytest.fixture @pytest.fixture
def super_user(client, session): def super_user(client):
settings_service = get_settings_service() settings_manager = get_settings_service()
auth_settings = settings_service.auth_settings auth_settings = settings_manager.auth_settings
return create_super_user( with session_getter(get_db_service()) as session:
db=session, return create_super_user(
username=auth_settings.FIRST_SUPERUSER, db=session,
password=auth_settings.FIRST_SUPERUSER_PASSWORD, username=auth_settings.SUPERUSER,
) password=auth_settings.SUPERUSER_PASSWORD,
)
@pytest.fixture @pytest.fixture
@ -23,8 +25,8 @@ def super_user_headers(client, super_user):
settings_service = get_settings_service() settings_service = get_settings_service()
auth_settings = settings_service.auth_settings auth_settings = settings_service.auth_settings
login_data = { login_data = {
"username": auth_settings.FIRST_SUPERUSER, "username": auth_settings.SUPERUSER,
"password": auth_settings.FIRST_SUPERUSER_PASSWORD, "password": auth_settings.SUPERUSER_PASSWORD,
} }
response = client.post("/api/v1/login", data=login_data) response = client.post("/api/v1/login", data=login_data)
assert response.status_code == 200 assert response.status_code == 200
@ -34,29 +36,34 @@ def super_user_headers(client, super_user):
@pytest.fixture @pytest.fixture
def deactivated_user(session): def deactivated_user():
user = User( with session_getter(get_db_manager()) as session:
username="deactivateduser", user = User(
password=get_password_hash("testpassword"), username="deactivateduser",
is_active=False, password=get_password_hash("testpassword"),
is_superuser=False, is_active=False,
last_login_at=datetime.now(), is_superuser=False,
) last_login_at=datetime.now(),
session.add(user) )
session.commit() session.add(user)
session.commit()
session.refresh(user)
return user return user
def test_user_waiting_for_approval(client, session): def test_user_waiting_for_approval(
client,
):
# Create a user that is not active and has never logged in # Create a user that is not active and has never logged in
user = User( with session_getter(get_db_manager()) as session:
username="waitingforapproval", user = User(
password=get_password_hash("testpassword"), username="waitingforapproval",
is_active=False, password=get_password_hash("testpassword"),
last_login_at=None, is_active=False,
) last_login_at=None,
session.add(user) )
session.commit() session.add(user)
session.commit()
login_data = {"username": "waitingforapproval", "password": "testpassword"} login_data = {"username": "waitingforapproval", "password": "testpassword"}
response = client.post("/api/v1/login", data=login_data) response = client.post("/api/v1/login", data=login_data)
@ -106,16 +113,17 @@ def test_data_consistency_after_delete(client, test_user, super_user_headers):
assert all(user["id"] != user_id for user in response.json()["users"]) assert all(user["id"] != user_id for user in response.json()["users"])
def test_inactive_user(client, session): def test_inactive_user(client):
# Create a user that is not active and has a last_login_at value # Create a user that is not active and has a last_login_at value
user = User( with session_getter(get_db_manager()) as session:
username="inactiveuser", user = User(
password=get_password_hash("testpassword"), username="inactiveuser",
is_active=False, password=get_password_hash("testpassword"),
last_login_at="2023-01-01T00:00:00", # Set to a valid datetime string is_active=False,
) last_login_at="2023-01-01T00:00:00", # Set to a valid datetime string
session.add(user) )
session.commit() session.add(user)
session.commit()
login_data = {"username": "inactiveuser", "password": "testpassword"} login_data = {"username": "inactiveuser", "password": "testpassword"}
response = client.post("/api/v1/login", data=login_data) response = client.post("/api/v1/login", data=login_data)

View file

@ -1,5 +1,5 @@
from fastapi.testclient import TestClient from fastapi.testclient import TestClient
from langflow.services.utils import get_settings_service from langflow.services.getters import get_settings_service
# check that all agents are in settings.agents # check that all agents are in settings.agents