From 9daf66993f77c0699a4e1368219b02ace011116a Mon Sep 17 00:00:00 2001 From: Gabriel Luiz Freitas Almeida Date: Fri, 14 Jun 2024 09:48:35 -0700 Subject: [PATCH 1/5] Refactor CustomComponent repr_value handling (#2173) * Refactor CustomComponent to handle repr_value more efficiently --- .../custom/custom_component/custom_component.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/base/langflow/custom/custom_component/custom_component.py b/src/backend/base/langflow/custom/custom_component/custom_component.py index 5c1da081b..963de3e28 100644 --- a/src/backend/base/langflow/custom/custom_component/custom_component.py +++ b/src/backend/base/langflow/custom/custom_component/custom_component.py @@ -159,11 +159,11 @@ class CustomComponent(Component): if self.repr_value == "": self.repr_value = self.status if isinstance(self.repr_value, dict): - return yaml.dump(self.repr_value) - if isinstance(self.repr_value, str): - return self.repr_value - if isinstance(self.repr_value, BaseModel) and not isinstance(self.repr_value, Record): - return str(self.repr_value) + self.repr_value = yaml.dump(self.repr_value) + if isinstance(self.repr_value, BaseModel) and not isinstance(self.repr_value, Data): + self.repr_value = str(self.repr_value) + elif hasattr(self.repr_value, "to_json"): + self.repr_value = self.repr_value.to_json() return self.repr_value def build_config(self): From 52e472798abff3550154443e91c8ae5d5c849f33 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Fri, 14 Jun 2024 13:53:27 -0300 Subject: [PATCH 2/5] chore: Update lint-action to v2 in lint-js.yml and lint-py.yml workflows --- .github/workflows/lint-js.yml | 2 +- .github/workflows/lint-py.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/lint-js.yml b/.github/workflows/lint-js.yml index 0590e8a38..84823b885 100644 --- a/.github/workflows/lint-js.yml +++ b/.github/workflows/lint-js.yml @@ -39,7 +39,7 @@ jobs: if: ${{ steps.setup-node.outputs.cache-hit != 'true' }} - name: Run linters - uses: wearerequired/lint-action@v1 + uses: wearerequired/lint-action@v2 with: github_token: ${{ secrets.github_token }} auto_fix: true diff --git a/.github/workflows/lint-py.yml b/.github/workflows/lint-py.yml index 6182f91fc..eb28b3101 100644 --- a/.github/workflows/lint-py.yml +++ b/.github/workflows/lint-py.yml @@ -41,7 +41,7 @@ jobs: ./.mypy_cache key: ${{ runner.os }}-mypy-${{ hashFiles('**/pyproject.toml') }} - name: Run linters - uses: wearerequired/lint-action@v1 + uses: wearerequired/lint-action@v2 with: github_token: ${{ secrets.github_token }} # Enable linters From 5353d2375a58d8438551c43d20f9fc2c76510dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=8Dtalo=20Johnny?= Date: Fri, 14 Jun 2024 14:01:24 -0300 Subject: [PATCH 3/5] Sentry integration (#2172) * add sentry sdk to dependencies * add sentry attributes to settings * initialize sentry for error tracking * add sentry sdk to base dependencies --- src/backend/base/langflow/main.py | 16 ++++++ .../base/langflow/services/settings/base.py | 5 ++ src/backend/base/poetry.lock | 53 ++++++++++++++++++- src/backend/base/pyproject.toml | 1 + 4 files changed, 73 insertions(+), 2 deletions(-) diff --git a/src/backend/base/langflow/main.py b/src/backend/base/langflow/main.py index c81c014e2..1227d4c62 100644 --- a/src/backend/base/langflow/main.py +++ b/src/backend/base/langflow/main.py @@ -20,6 +20,7 @@ from langflow.initial_setup.setup import ( load_flows_from_directory, ) from langflow.interface.utils import setup_llm_caching +from langflow.services.deps import get_settings_service from langflow.services.plugins.langfuse_plugin import LangfuseInstance from langflow.services.utils import initialize_services, teardown_services from langflow.utils.logger import configure @@ -78,6 +79,7 @@ def create_app(): socketio_server = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*", logger=True) lifespan = get_lifespan(socketio_server=socketio_server, version=__version__) app = FastAPI(lifespan=lifespan, title="Langflow", version=__version__) + setup_sentry(app) origins = ["*"] app.add_middleware( @@ -115,6 +117,20 @@ def mount_socketio(app: FastAPI, socketio_server: socketio.AsyncServer): return app +def setup_sentry(app: FastAPI): + settings = get_settings_service().settings + if settings.sentry_dsn: + import sentry_sdk + from sentry_sdk.integrations.asgi import SentryAsgiMiddleware + + sentry_sdk.init( + dsn=settings.sentry_dsn, + traces_sample_rate=settings.sentry_traces_sample_rate, + profiles_sample_rate=settings.sentry_profiles_sample_rate, + ) + app.add_middleware(SentryAsgiMiddleware) + + def setup_static_files(app: FastAPI, static_files_dir: Path): """ Setup the static files directory. diff --git a/src/backend/base/langflow/services/settings/base.py b/src/backend/base/langflow/services/settings/base.py index 679d16627..e8c0cbf90 100644 --- a/src/backend/base/langflow/services/settings/base.py +++ b/src/backend/base/langflow/services/settings/base.py @@ -85,6 +85,11 @@ class Settings(BaseSettings): redis_url: Optional[str] = None redis_cache_expire: int = 3600 + # Sentry + sentry_dsn: Optional[str] = None + sentry_traces_sample_rate: Optional[float] = 1.0 + sentry_profiles_sample_rate: Optional[float] = 1.0 + # PLUGIN_DIR: Optional[str] = None langfuse_secret_key: Optional[str] = None diff --git a/src/backend/base/poetry.lock b/src/backend/base/poetry.lock index 8f57c7d7b..7f21e0c5f 100644 --- a/src/backend/base/poetry.lock +++ b/src/backend/base/poetry.lock @@ -2411,7 +2411,6 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, @@ -2499,6 +2498,56 @@ files = [ [package.dependencies] pyasn1 = ">=0.1.3" +[[package]] +name = "sentry-sdk" +version = "2.5.1" +description = "Python client for Sentry (https://sentry.io)" +optional = false +python-versions = ">=3.6" +files = [ + {file = "sentry_sdk-2.5.1-py2.py3-none-any.whl", hash = "sha256:1f87acdce4a43a523ae5aa21a3fc37522d73ebd9ec04b1dbf01aa3d173852def"}, + {file = "sentry_sdk-2.5.1.tar.gz", hash = "sha256:fbc40a78a8a9c6675133031116144f0d0940376fa6e4e1acd5624c90b0aaf58b"}, +] + +[package.dependencies] +certifi = "*" +urllib3 = ">=1.26.11" + +[package.extras] +aiohttp = ["aiohttp (>=3.5)"] +anthropic = ["anthropic (>=0.16)"] +arq = ["arq (>=0.23)"] +asyncpg = ["asyncpg (>=0.23)"] +beam = ["apache-beam (>=2.12)"] +bottle = ["bottle (>=0.12.13)"] +celery = ["celery (>=3)"] +celery-redbeat = ["celery-redbeat (>=2)"] +chalice = ["chalice (>=1.16.0)"] +clickhouse-driver = ["clickhouse-driver (>=0.2.0)"] +django = ["django (>=1.8)"] +falcon = ["falcon (>=1.4)"] +fastapi = ["fastapi (>=0.79.0)"] +flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"] +grpcio = ["grpcio (>=1.21.1)", "protobuf (>=3.8.0)"] +httpx = ["httpx (>=0.16.0)"] +huey = ["huey (>=2)"] +huggingface-hub = ["huggingface-hub (>=0.22)"] +langchain = ["langchain (>=0.0.210)"] +loguru = ["loguru (>=0.5)"] +openai = ["openai (>=1.0.0)", "tiktoken (>=0.3.0)"] +opentelemetry = ["opentelemetry-distro (>=0.35b0)"] +opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] +pure-eval = ["asttokens", "executing", "pure-eval"] +pymongo = ["pymongo (>=3.1)"] +pyspark = ["pyspark (>=2.4.4)"] +quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] +rq = ["rq (>=0.6)"] +sanic = ["sanic (>=0.8)"] +sqlalchemy = ["sqlalchemy (>=1.2)"] +starlette = ["starlette (>=0.19.1)"] +starlite = ["starlite (>=1.48)"] +tornado = ["tornado (>=5)"] + [[package]] name = "shellingham" version = "1.5.4" @@ -3247,4 +3296,4 @@ local = [] [metadata] lock-version = "2.0" python-versions = ">=3.10,<3.13" -content-hash = "3c83d086a178cebd83473758459c4f026907268dbf8c9ce45bc4bfb1f340e9a5" +content-hash = "72f05330f1e734596d160b45cb68ab2ebf7d0824314bec0566bddb5b2043f4e6" diff --git a/src/backend/base/pyproject.toml b/src/backend/base/pyproject.toml index a833470a2..1762b645d 100644 --- a/src/backend/base/pyproject.toml +++ b/src/backend/base/pyproject.toml @@ -63,6 +63,7 @@ cryptography = "^42.0.5" asyncer = "^0.0.5" pyperclip = "^1.8.2" uncurl = "^0.0.11" +sentry-sdk = "^2.5.1" [tool.poetry.extras] From 49962aeb571448e14ae5bf2006ad007df16ec92a Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Fri, 14 Jun 2024 14:19:06 -0300 Subject: [PATCH 4/5] chore: Update Dockerfile and Tags setup in docker-build.yml workflow --- .github/workflows/docker-build.yml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index c5ea5f6f7..3450f317e 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -26,15 +26,17 @@ jobs: setup: runs-on: ubuntu-latest outputs: - base_tags: ${{ steps.set-vars.outputs.base_tags }} - main_tags: ${{ steps.set-vars.outputs.main_tags }} + tags: ${{ steps.set-vars.outputs.tags }} steps: - uses: actions/checkout@v4 - name: Set Dockerfile and Tags id: set-vars run: | - echo "base_tags=langflowai/langflow:base-${{ inputs.version }}" >> $GITHUB_OUTPUT - echo "main_tags=langflowai/langflow:${{ inputs.version }},langflowai/langflow:1.0-alpha" >> $GITHUB_OUTPUT + if [[ "${{ inputs.release_type }}" == "base" ]]; then + echo "tags=langflowai/langflow:base-${{ inputs.version }}" >> $GITHUB_OUTPUT + else + echo "tags=langflowai/langflow:${{ inputs.version }},langflowai/langflow:1.0-alpha" >> $GITHUB_OUTPUT + fi build_base: runs-on: ubuntu-latest needs: setup @@ -54,7 +56,10 @@ jobs: push: true platforms: "linux/amd64,linux/arm64/v8" file: ./docker/build_and_push_base.Dockerfile - tags: ${{ needs.setup.outputs.base_tags }} + # base_rags if release_type is base, main_tags if release_type is main + tags: ${{ needs.setup.outputs.tags }} + - name: Wait for Docker Hub to propagate + run: sleep 30 build_components: if: ${{ inputs.release_type == 'main' }} From 3c430ff397f19ab19ef2b6405f2b938fdf529355 Mon Sep 17 00:00:00 2001 From: ogabrielluiz Date: Fri, 14 Jun 2024 14:29:51 -0300 Subject: [PATCH 5/5] chore: Update Dockerfile and Tags setup in docker-build.yml workflow --- .github/workflows/docker-build.yml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml index 3450f317e..f84dead6b 100644 --- a/.github/workflows/docker-build.yml +++ b/.github/workflows/docker-build.yml @@ -40,6 +40,10 @@ jobs: build_base: runs-on: ubuntu-latest needs: setup + strategy: + matrix: + platform: [linux/amd64, linux/arm64/v8] + file: [./docker/build_and_push.Dockerfile, ./docker/build_and_push_base.Dockerfile] steps: - uses: actions/checkout@v4 - name: Set up Docker Buildx @@ -54,12 +58,9 @@ jobs: with: context: . push: true - platforms: "linux/amd64,linux/arm64/v8" - file: ./docker/build_and_push_base.Dockerfile - # base_rags if release_type is base, main_tags if release_type is main + platforms: ${{ matrix.platform }} + file: ${{ matrix.file }} tags: ${{ needs.setup.outputs.tags }} - - name: Wait for Docker Hub to propagate - run: sleep 30 build_components: if: ${{ inputs.release_type == 'main' }}