Repository: truera/trulens
Issue: [BUG] A non-annotated attribute was detected: `TABLE_META = 'meta'`
Root cause: External Dependency Breakage

**Bug Description**
What happened?

trying to import and got:



```
A non-annotated attribute was detected: `TABLE_META = 'meta'`. All model fields require a type annotation; if `TABLE_META` is not meant to be a field, you may be able to resolve this error by annotating it as a `ClassVar` or updating `model_config['ignored_types']`
```


**To Reproduce**
```
pip install trulens_eval
from trulens_eval import Tru
```

**Expected behavior**
it should work

**Relevant Logs/Tracebacks**
Please copy and paste any relevant log output. This will be automatically formatted into code, so no need for backticks. If the issue is related to the TruLens dashboard, please also include a screenshot.

```
{
	"name": "PydanticUserError",
	"message": "A non-annotated attribute was detected: `TABLE_META = 'meta'`. All model fields require a type annotation; if `TABLE_META` is not meant to be a field, you may be able to resolve this error by annotating it as a `ClassVar` or updating `model_config['ignored_types']`.

For further information visit https://errors.pydantic.dev/2.6/u/model-field-missing-annotation",
	"stack": "---------------------------------------------------------------------------
PydanticUserError                         Traceback (most recent call last)
Cell In[81], line 1
----> 1 from trulens_eval import Tru

File ~/.pyenv/versions/3.12.0/lib/python3.12/site-packages/trulens_eval/__init__.py:91
     89 from trulens_eval.schema import Query
     90 from trulens_eval.schema import Select
---> 91 from trulens_eval.tru import Tru
     92 from trulens_eval.tru_basic_app import TruBasicApp
     93 from trulens_eval.tru_chain import TruChain

File ~/.pyenv/versions/3.12.0/lib/python3.12/site-packages/trulens_eval/tru.py:15
     11 import warnings
     13 import pkg_resources
---> 15 from trulens_eval.database.sqlalchemy_db import SqlAlchemyDB
     16 from trulens_eval.db import JSON
     17 from trulens_eval.feedback import Feedback

File ~/.pyenv/versions/3.12.0/lib/python3.12/site-packages/trulens_eval/database/sqlalchemy_db.py:26
     24 from trulens_eval.database.orm import FeedbackResult
     25 from trulens_eval.database.orm import Record
---> 26 from trulens_eval.database.utils import check_db_revision
     27 from trulens_eval.database.utils import for_all_methods
     28 from trulens_eval.database.utils import is_legacy_sqlite

File ~/.pyenv/versions/3.12.0/lib/python3.12/site-packages/trulens_eval/database/utils.py:19
     17 from trulens_eval.database.migrations import DbRevisions
     18 from trulens_eval.database.migrations import upgrade_db
---> 19 from trulens_eval.db import LocalSQLite
     21 logger = logging.getLogger(__name__)
     24 def for_all_methods(decorator, _except: Optional[List[str]] = None):

File ~/.pyenv/versions/3.12.0/lib/python3.12/site-packages/trulens_eval/db.py:186
    180         return cls
    182     return decorate
    185 @for_all_methods(versioning_decorator)
--> 186 class LocalSQLite(DB):
    187     filename: Path
    189     TABLE_META = \"meta\"

File ~/.pyenv/versions/3.12.0/lib/python3.12/site-packages/pydantic/_internal/_model_construction.py:92, in ModelMetaclass.__new__(mcs, cls_name, bases, namespace, __pydantic_generic_metadata__, __pydantic_reset_parent_namespace__, _create_model_module, **kwargs)
     90 config_wrapper = ConfigWrapper.for_model(bases, namespace, kwargs)
     91 namespace['model_config'] = config_wrapper.config_dict
---> 92 private_attributes = inspect_namespace(
     93     namespace, config_wrapper.ignored_types, class_vars, base_field_names
     94 )
     95 if private_attributes:
     96     original_model_post_init = get_model_post_init(namespace, bases)

File ~/.pyenv/versions/3.12.0/lib/python3.12/site-packages/pydantic/_internal/_model_construction.py:384, in inspect_namespace(namespace, ignored_types, base_class_vars, base_class_fields)
    380             raise PydanticUserError(
    381                 f'Field {var_name!r} requires a type annotation', code='model-field-missing-annotation'
    382             )
    383         else:
--> 384             raise PydanticUserError(
    385                 f'A non-annotated attribute was detected: `{var_name} = {value!r}`. All model fields require a '
    386                 f'type annotation; if `{var_name}` is not meant to be a field, you may be able to resolve this '
    387                 f\"error by annotating it as a `ClassVar` or updating `model_config['ignored_types']`.\",
    388                 code='model-field-missing-annotation',
    389             )
    391 for ann_name, ann_type in raw_annotations.items():
    392     if (
    393         is_valid_privateattr_name(ann_name)
    394         and ann_name not in private_attributes
   (...)
    398         and getattr(ann_type, '__module__', None) != 'functools'
    399     ):

PydanticUserError: A non-annotated attribute was detected: `TABLE_META = 'meta'`. All model fields require a type annotation; if `TABLE_META` is not meant to be a field, you may be able to resolve this error by annotating it as a `ClassVar` or updating `model_config['ignored_types']`.

For further information visit https://errors.pydantic.dev/2.6/u/model-field-missing-annotation"
}
```

**Environment:**
 - OS: Linux DESKTOP-E0TQLRG 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
 - Python Version 3.12.0
 - TruLens version latest
 - Versions of other relevant installed libraries

aiohttp==3.9.3
aiosignal==1.3.1
alembic==1.13.1
altair==5.2.0
annotated-types==0.6.0
anyio==4.3.0
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
arrow==1.3.0
asttokens==2.4.1
async-lru==2.0.4
attrs==23.2.0
azure-core==1.30.1
azure-identity==1.15.0
Babel==2.14.0
backoff==2.2.1
beautifulsoup4==4.12.3
bleach==6.1.0
blinker==1.7.0
bs4==0.0.2
cachetools==5.3.3
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
cohere==4.57
comm==0.2.2
contourpy==1.2.0
cryptography==42.0.5
cycler==0.12.1
dataclasses-json==0.6.4
datasets==2.18.0
debugpy==1.8.1
decorator==5.1.1
defusedxml==0.7.1
Deprecated==1.2.14
dill==0.3.8
dirtyjson==1.0.8
distro==1.9.0
entrypoints==0.4
executing==2.0.1
Faker==24.3.0
fastavro==1.9.4
fastjsonschema==2.19.1
favicon==0.7.0
filelock==3.13.1
fonttools==4.50.0
fqdn==1.5.1
frozendict==2.4.0
frozenlist==1.4.1
fsspec==2024.2.0
gitdb==4.0.11
GitPython==3.1.42
greenlet==3.0.3
h11==0.14.0
htbuilder==0.6.2
httpcore==1.0.4
httpx==0.27.0
huggingface-hub==0.21.4
idna==3.6
importlib-metadata==6.11.0
install==1.3.5
ipykernel==6.29.3
ipython==8.22.2
ipywidgets==8.1.2
isoduration==20.11.0
jedi==0.19.1
Jinja2==3.1.3
joblib==1.3.2
json5==0.9.24
jsonpatch==1.33
jsonpointer==2.4
jsonschema==4.21.1
jsonschema-specifications==2023.12.1
jupyter-console==6.6.3
jupyter-events==0.10.0
jupyter-lsp==2.2.4
jupyter_client==8.6.1
jupyter_core==5.7.2
jupyter_server==2.13.0
jupyter_server_terminals==0.5.3
jupyterlab==4.1.5
jupyterlab_pygments==0.3.0
jupyterlab_server==2.25.4
jupyterlab_widgets==3.0.10
kaggle==1.6.6
kiwisolver==1.4.5
langchain==0.1.12
langchain-community==0.0.28
langchain-core==0.1.32
langchain-text-splitters==0.0.1
langsmith==0.1.31
litellm==1.32.7
llama-index==0.10.20
llama-index-agent-openai==0.1.5
llama-index-cli==0.1.9
llama-index-core==0.10.20.post2
llama-index-embeddings-azure-openai==0.1.6
llama-index-embeddings-huggingface==0.1.4
llama-index-embeddings-openai==0.1.6
llama-index-indices-managed-llama-cloud==0.1.4
llama-index-legacy==0.9.48
llama-index-llms-azure-openai==0.1.5
llama-index-llms-openai==0.1.12
llama-index-multi-modal-llms-openai==0.1.4
llama-index-program-openai==0.1.4
llama-index-question-gen-openai==0.1.3
llama-index-readers-file==0.1.11
llama-index-readers-llama-parse==0.1.3
llama-index-vector-stores-pinecone==0.1.4
llama-parse==0.3.9
llamaindex-py-client==0.1.13
lxml==5.1.0
Mako==1.3.2
Markdown==3.6
markdown-it-py==3.0.0
markdownlit==0.0.7
MarkupSafe==2.1.5
marshmallow==3.21.1
matplotlib==3.8.3
matplotlib-inline==0.1.6
mdurl==0.1.2
merkle-json==1.0.0
millify==0.1.1
mistune==3.0.2
more-itertools==10.2.0
mpmath==1.3.0
msal==1.28.0
msal-extensions==1.1.0
multidict==6.0.5
multiprocess==0.70.16
munch==4.0.0
mypy-extensions==1.0.0
nbclient==0.10.0
nbconvert==7.16.2
nbformat==5.10.3
nest-asyncio==1.6.0
networkx==3.2.1
nltk==3.8.1
notebook==7.1.2
notebook_shim==0.2.4
numpy==1.26.4
nvidia-cublas-cu12==12.1.3.1
nvidia-cuda-cupti-cu12==12.1.105
nvidia-cuda-nvrtc-cu12==12.1.105
nvidia-cuda-runtime-cu12==12.1.105
nvidia-cudnn-cu12==8.9.2.26
nvidia-cufft-cu12==11.0.2.54
nvidia-curand-cu12==10.3.2.106
nvidia-cusolver-cu12==11.4.5.107
nvidia-cusparse-cu12==12.1.0.106
nvidia-nccl-cu12==2.19.3
nvidia-nvjitlink-cu12==12.4.99
nvidia-nvtx-cu12==12.1.105
openai==1.5.0
orjson==3.9.15
overrides==7.7.0
packaging==23.2
pandas==2.2.1
pandocfilters==1.5.1
parso==0.8.3
pexpect==4.9.0
pillow==10.2.0
pinecone-client==3.1.0
platformdirs==4.2.0
portalocker==2.8.2
prometheus_client==0.20.0
prompt-toolkit==3.0.43
protobuf==4.25.3
psutil==5.9.8
ptyprocess==0.7.0
pure-eval==0.2.2
pyarrow==15.0.2
pyarrow-hotfix==0.6
pycparser==2.21
pydantic==2.6.4
pydantic_core==2.16.3
pydeck==0.8.1b0
Pygments==2.17.2
PyJWT==2.8.0
pymdown-extensions==10.7.1
PyMuPDF==1.23.26
PyMuPDFb==1.23.22
pyOpenSSL==24.0.0
pyparsing==3.1.2
pypdf==4.1.0
python-dateutil==2.9.0.post0
python-decouple==3.8
python-dotenv==1.0.1
python-json-logger==2.0.7
python-slugify==8.0.4
pytz==2024.1
PyYAML==6.0.1
pyzmq==25.1.2
qtconsole==5.5.1
QtPy==2.4.1
referencing==0.34.0
regex==2023.12.25
requests==2.31.0
rfc3339-validator==0.1.4
rfc3986-validator==0.1.1
rich==13.7.1
rpds-py==0.18.0
safetensors==0.4.2
Send2Trash==1.8.2
setuptools==69.2.0
six==1.16.0
slack-bolt==1.18.1
slack_sdk==3.27.1
smmap==5.0.1
sniffio==1.3.1
soupsieve==2.5
SQLAlchemy==2.0.24
st-annotated-text==4.0.1
stack-data==0.6.3
streamlit==1.32.2
streamlit-aggrid==0.3.4.post3
streamlit-camera-input-live==0.2.0
streamlit-card==1.0.0
streamlit-embedcode==0.1.2
streamlit-extras==0.4.0
streamlit-faker==0.0.3
streamlit-image-coordinates==0.1.6
streamlit-javascript==0.1.5
streamlit-keyup==0.2.3
streamlit-toggle-switch==1.0.2
streamlit-vertical-slider==2.5.5
striprtf==0.0.26
sympy==1.12
tenacity==8.2.3
terminado==0.18.1
text-unidecode==1.3
tiktoken==0.6.0
tinycss2==1.2.1
tokenizers==0.15.2
toml==0.10.2
toolz==0.12.1
torch==2.2.1
tornado==6.4
tqdm==4.66.2
traitlets==5.14.2
transformers==4.38.2
trulens-eval==0.14.0
types-python-dateutil==2.9.0.20240316
typing-inspect==0.8.0
typing_extensions==4.10.0
tzdata==2024.1
uri-template==1.3.0
urllib3==2.2.1
watchdog==4.0.0
wcwidth==0.2.13
webcolors==1.13
webencodings==0.5.1
websocket-client==1.7.0
widgetsnbextension==4.0.10
wrapt==1.16.0
xxhash==3.4.1
yarl==1.9.4
zipp==3.18.1

**Additional context**
Add any other context about the problem here.


<!-- Answer -->
Based on the error message you provided, it seems like the issue is related to the `pydantic` library's data validation. The `pydantic` library is used for data parsing and validation using Python type annotations. In your case, the error message suggests that the `TABLE_META` attribute in the `LocalSQLite` class in the `db.py` file is not annotated.

Python 3.12 introduced stricter checks for class attributes to distinguish them from SQLAlchemy model fields. If `TABLE_META = 'meta'` or a similar attribute is defined within a SQLAlchemy model class and is not intended to be a database field, you should annotate it with `typing.ClassVar` to indicate that it is a class-level attribute and not a field.

Here's an example of how to annotate class-level attributes correctly:

```python
from typing import ClassVar

class SomeModel(Base):
    __tablename__ = 'some_table'
    id = Column(Integer, primary_key=True)
    # Example of a non-field attribute that should be annotated
    TABLE_META: ClassVar[str] = 'meta'
```

This change informs both the Python interpreter and SQLAlchemy that `TABLE_META` is not a database field but a regular class attribute, preventing the error you encountered. 

Ensure you apply this change to the correct class or classes within your codebase where `TABLE_META = 'meta'` or any similar non-field attributes are defined.

Regarding the `LocalSQLite` class in the `db.py` file of the trulens repository, it is a class that handles the operations of a local SQLite database. It has several class-level attributes, including `TABLE_META`, which are used to define the names of the tables in the database. These attributes should be annotated as `ClassVar` to avoid the error you're encountering.

Unfortunately, I don't have the information about the exact version of the `pydantic` library you have installed. You can check this by running `pip show pydantic` in your terminal. If the version is not compatible with the trulens library, you might need to upgrade or downgrade it.

I hope this helps! If you have any other questions or need further clarification, feel free to ask.

## Sources
- [trulens_eval/trulens_eval/tru.py](https://github.com/truera/trulens/blob/main/trulens_eval/trulens_eval/tru.py)
- [trulens_eval/trulens_eval/db.py](https://github.com/truera/trulens/blob/main/trulens_eval/trulens_eval/db.py)

<!-- Dosu Comment Footer -->
<details open>
<summary>

#### About Dosu
</summary>

This response is meant to be useful and save you time. It is **not meant to be a precise solution**, but rather a starting point for your own research.

Help me be more useful! Please leave a 👍 if this is helpful and 👎 if it is irrelevant.

If you want to continue the conversation, start your reply with @dosu-bot.
</details>

Name: pydantic
Version: 1.10.14
Summary: Data validation and settings management using python type hints
Home-page: https://github.com/pydantic/pydantic
Author: Samuel Colvin
Author-email: s@muelcolvin.com
License: MIT
Location: /home/gubert/.pyenv/versions/3.12.0/lib/python3.12/site-packages
Requires: typing-extensions
Required-by: langchain, langchain-core, langsmith, llamaindex-py-client, openai, trulens-eval


Het @guybartal - we don’t support python 3.12 yet (coming in the next release later this week). Can you try downgrading your python version?

Please reopen if not resolved on lower python version

got it, thanks for letting me know!

Hey @guybartal - python 3.12 support is now available in 0.27.0!

Please upgrade your trulens-eval version `pip install -U trulens-eval` and let me know if you have any issues - thanks!