Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

class dispatch suggestion #1360

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,6 @@ repos:
- id: poetry-check
name: trulens-providers-openai-poetry-check
args: [-C src/providers/openai]
- id: poetry-check
name: trulens-workspaces-snowflake-poetry-check
args: [-C src/workspaces/snowflake]
7 changes: 6 additions & 1 deletion docs/gen_ref_pages.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,12 @@ def write_to_gen_files(
instrument_packages = [
f"instrument/{pkg_dir}" for pkg_dir in next(os.walk("src/instrument"))[1]
]
packages = core_packages + provider_packages + instrument_packages
workspace_packages = [
f"workspaces/{pkg_dir}" for pkg_dir in next(os.walk("src/workspaces"))[1]
]
packages = (
core_packages + provider_packages + instrument_packages + workspace_packages
)
print("Collecting from packages:", packages)

# Write Index Page
Expand Down
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ plugins:
- src/providers/langchain
- src/providers/litellm
- src/providers/openai
- src/workspaces/snowflake
options:

heading_level: 2
Expand Down
127 changes: 70 additions & 57 deletions poetry.lock

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ trulens-providers-huggingface = { path = "src/providers/huggingface", develop =
trulens-providers-openai = { path = "src/providers/openai", develop = true }
trulens-providers-litellm = { path = "src/providers/litellm", develop = true }

[tool.poetry.group.workspaces.dependencies]
trulens-workspaces-snowflake = { path = "src/workspaces/snowflake", develop = true, python = "<3.12" }

[tool.poetry.group.required.dependencies]
python = "^3.9,!=3.9.7"
trulens-core = { path = "src/core", extras = [
"snowflake",
], develop = true }
trulens-core = { path = "src/core", develop = true }
trulens-feedback = { path = "src/feedback", develop = true }
trulens-dashboard = { path = "src/dashboard", develop = true, python = "!=3.9.7" }

Expand Down
3 changes: 0 additions & 3 deletions src/benchmark/poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

614 changes: 4 additions & 610 deletions src/core/poetry.lock

Large diffs are not rendered by default.

11 changes: 0 additions & 11 deletions src/core/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ sqlalchemy = "^2.0"
alembic = "^1.8.1"
nest-asyncio = "^1.5"
python-dotenv = ">=0.21,<2.0"

snowflake-connector-python = { version = "^3.11", python = "<3.12", optional = true }
snowflake-snowpark-python = { version = "^1.18", python = "<3.12", optional = true }
snowflake-sqlalchemy = { version = "^1.6", python = "<3.12", optional = true }
tqdm = { version = ">=4.2.0", optional = true }

[tool.poetry.group.openai]
Expand All @@ -51,10 +47,3 @@ optional = true
[tool.poetry.group.openai.dependencies]
openai = "^1.37"
httpx = "^0.27"

[tool.poetry.extras]
snowflake = [
"snowflake-connector-python",
"snowflake-snowpark-python",
"snowflake-sqlalchemy",
]
54 changes: 23 additions & 31 deletions src/core/trulens/core/app/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from inspect import BoundArguments
from inspect import Signature
import logging
from pprint import PrettyPrinter
import threading
from threading import Lock
from typing import (
Expand All @@ -31,7 +30,6 @@
)

import pydantic
from trulens.core import tru as mod_tru
from trulens.core.database import base as mod_db
import trulens.core.feedback as mod_feedback
import trulens.core.instruments as mod_instruments
Expand Down Expand Up @@ -64,11 +62,11 @@
from trulens.core.utils.serial import GetItemOrAttribute
from trulens.core.utils.serial import Lens
from trulens.core.utils.serial import all_objects
from trulens.core.workspace.base import BaseWorkspace
from trulens.core.workspace.default import DefaultWorkspace

logger = logging.getLogger(__name__)

pp = PrettyPrinter()

# App component.
COMPONENT = Any

Expand Down Expand Up @@ -481,10 +479,10 @@ class App(
)
"""Feedback functions to evaluate on each record."""

tru: Optional[mod_tru.Tru] = pydantic.Field(default=None, exclude=True)
workspace: BaseWorkspace = pydantic.Field(default=None, exclude=True)
"""Workspace manager.

If this is not povided, a singleton [Tru][trulens.core.tru.Tru] will be made
If this is not provided, a singleton [Tru][trulens.core.tru.Tru] will be made
(if not already) and used.
"""

Expand All @@ -511,7 +509,7 @@ class App(
recording_contexts: contextvars.ContextVar[RecordingContext] = (
pydantic.Field(None, exclude=True)
)
"""Sequnces of records produced by the this class used as a context manager
"""Sequences of records produced by the this class used as a context manager
are stored in a RecordingContext.

Using a context var so that context managers can be nested.
Expand Down Expand Up @@ -552,7 +550,7 @@ class App(

def __init__(
self,
tru: Optional[mod_tru.Tru] = None,
workspace: Optional[BaseWorkspace] = None,
feedbacks: Optional[Iterable[mod_feedback.Feedback]] = None,
**kwargs,
):
Expand All @@ -562,7 +560,7 @@ def __init__(
feedbacks = []

# for us:
kwargs["tru"] = tru
kwargs["workspace"] = workspace
kwargs["feedbacks"] = feedbacks
kwargs["recording_contexts"] = contextvars.ContextVar(
"recording_contexts"
Expand Down Expand Up @@ -596,7 +594,7 @@ def _start_manage_pending_feedback_results(self) -> None:
"""Start the thread that manages the queue of records with
pending feedback results.

This is meant to be run permentantly in a separate thread. It will
This is meant to be run permanently in a separate thread. It will
remove records from the set `records_with_pending_feedback_results` as
their feedback results are computed.
"""
Expand Down Expand Up @@ -681,30 +679,26 @@ def _tru_post_init(self):

"""

if self.tru is None:
if self.workspace is None:
if self.feedback_mode != mod_feedback_schema.FeedbackMode.NONE:
from trulens.core.tru import Tru

logger.debug("Creating default tru.")
self.tru = Tru()
logger.debug("Creating default Workspace.")
self.workspace = DefaultWorkspace()

else:
if self.feedback_mode == mod_feedback_schema.FeedbackMode.NONE:
logger.warning(
"`tru` is specified but `feedback_mode` is FeedbackMode.NONE. "
"`workspace` is specified but `feedback_mode` is `FeedbackMode.NONE`. "
"No feedback evaluation and logging will occur."
)

if self.tru is not None:
self.db = self.tru.db

self.db.insert_app(app=self)
if self.workspace is not None:
self.workspace.add_app(app=self)

if self.feedback_mode != mod_feedback_schema.FeedbackMode.NONE:
logger.debug("Inserting feedback function definitions to db.")

for f in self.feedbacks:
self.db.insert_feedback_definition(f)
self.workspace.add_feedback_definition(f)

else:
if len(self.feedbacks) > 0:
Expand Down Expand Up @@ -1360,7 +1354,7 @@ def _add_future_feedback(
else:
res = future_or_result

self.tru.add_feedback(res)
self.workspace.add_feedback(res)

def _handle_record(
self,
Expand All @@ -1383,27 +1377,24 @@ def _handle_record(
if feedback_mode is None:
feedback_mode = self.feedback_mode

if self.tru is None or self.feedback_mode is None:
if self.feedback_mode is None:
return None

self.tru: mod_tru.Tru
self.db: mod_db.DB

# If in buffered mode, call add record nowait.
if self.record_ingest_mode == mod_app_schema.RecordIngestMode.BUFFERED:
self.tru.add_record_nowait(record=record)
self.workspace.add_record_nowait(record=record)
return

# Need to add record to db before evaluating feedback functions.
record_id = self.tru.add_record(record=record)
record_id = self.workspace.add_record(record=record)

if len(self.feedbacks) == 0:
return []

# Add empty (to run) feedback to db.
if feedback_mode == mod_feedback_schema.FeedbackMode.DEFERRED:
for f in self.feedbacks:
self.db.insert_feedback(
self.workspace.add_feedback(
mod_feedback_schema.FeedbackResult(
name=f.name,
record_id=record_id,
Expand All @@ -1417,15 +1408,16 @@ def _handle_record(
mod_feedback_schema.FeedbackMode.WITH_APP,
mod_feedback_schema.FeedbackMode.WITH_APP_THREAD,
]:
return self.tru._submit_feedback_functions(
return self._submit_feedback_functions(
record=record,
feedback_functions=self.feedbacks,
workspace=self.workspace,
app=self,
on_done=self._add_future_feedback,
)

def _handle_error(self, record: mod_record_schema.Record, error: Exception):
if self.db is None:
if self.workspace is None:
return

def __getattr__(self, __name: str) -> Any:
Expand Down
23 changes: 19 additions & 4 deletions src/core/trulens/core/database/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from trulens.core.schema.feedback import FeedbackResultStatus
from trulens.core.schema.record import Record
from trulens.core.utils.json import json_str_of_obj
from trulens.core.utils.serial import JSON
from trulens.core.utils.serial import JSONized
from trulens.core.utils.serial import SerialModel

Expand Down Expand Up @@ -65,7 +64,7 @@ def reset_database(self):

@abc.abstractmethod
def migrate_database(self, prior_prefix: Optional[str] = None):
"""Migrade the stored data to the current configuration of the database.
"""Migrate the stored data to the current configuration of the database.

Args:
prior_prefix: If given, the database is assumed to have been
Expand Down Expand Up @@ -133,6 +132,22 @@ def insert_app(self, app: AppDefinition) -> mod_types_schema.AppID:

raise NotImplementedError()

@abc.abstractmethod
def delete_app(self, app_id: mod_types_schema.AppID) -> None:
"""
Delete an `app` from the database.

Args:
app: The app to delete. Note that only the
[AppDefinition][trulens.core.schema.app.AppDefinition] parts are serialized
hence the type hint.

Returns:
The id of the given app.
"""

raise NotImplementedError()

@abc.abstractmethod
def insert_feedback_definition(
self, feedback_definition: FeedbackDefinition
Expand Down Expand Up @@ -292,7 +307,7 @@ def get_app(self, app_id: mod_types_schema.AppID) -> Optional[JSONized]:
raise NotImplementedError()

@abc.abstractmethod
def get_apps(self) -> Iterable[JSON]:
def get_apps(self) -> Iterable[JSONized[AppDefinition]]:
"""Get all apps."""

raise NotImplementedError()
Expand All @@ -315,7 +330,7 @@ def get_records_and_feedback(
limit: Limit on rows (records) returned.

Returns:
A dataframe with the records.
A DataFrame with the records.

A list of column names that contain feedback results.
"""
Expand Down
2 changes: 1 addition & 1 deletion src/core/trulens/core/database/migrations/alembic.ini
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ version_path_separator = os # Use os.pathsep. Default configuration used for ne
# are written from script.py.mako
# output_encoding = utf-8

sqlalchemy.url = ""
sqlalchemy.url =

# [post_write_hooks]
# post_write_hooks defines scripts or Python functions that are run
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"""set feedback function id to not nullable.

Revision ID: 3
Revises: 2
Create Date: 2024-08-16 12:44:05.560492
"""

from alembic import op

# revision identifiers, used by Alembic.
revision = "3"
down_revision = "2"
branch_labels = None
depends_on = "1"


def upgrade(config) -> None:
prefix = config.get_main_option("trulens.table_prefix")

if prefix is None:
raise RuntimeError("trulens.table_prefix is not set")

# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table(prefix + "feedbacks") as batch_op:
batch_op.alter_column(
"feedback_definition_id",
nullable=False,
)
# ### end Alembic commands ###


def downgrade(config) -> None:
prefix = config.get_main_option("trulens.prefix")

# ### commands auto generated by Alembic - please adjust! ###
with op.batch_alter_table(prefix + "feedbacks") as batch_op:
batch_op.alter_column(
"feedback_definition_id",
nullable=True,
)
# ### end Alembic commands ###
Loading