Repository: truera/trulens
Issue: [BUG] Tru was already initialized. Cannot change database_url
Root cause: Validation Gap

**Bug Description**
What happened?

```bash
🦑 Tru initialized with db url sqlite:///default.sqlite .

🛑 Secret keys may be written to the database. See the `database_redact_keys` option of Tru` to prevent this.

Tru was already initialized. Cannot change database_url=sqlite:///default.sqlite or database_file=None .

Tru was already initialized. Cannot change database_url=sqlite:///default.sqlite or database_file=None .

Tru was already initialized. Cannot change database_url=sqlite:///default.sqlite or database_file=None .
```

**To Reproduce**
Which steps should someone take to run into the same error? A small, reproducible code example is useful here.

**Expected behavior**
A clear and concise description of what you expected to happen.

**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.

**Environment:**
 - OS: [e.g. MacOS, Windows]
 - Python Version
 - TruLens version
 - Versions of other relevant installed libraries

**Additional context**
Add any other context about the problem here.


<!-- Greeting -->
Hey there @liuxiaocs7! Good to see you back 🌟. Ran into a bit of a snag, huh? Let's see what we can do about it!

<!-- Answer -->
Based on the error message you've provided, it seems like the Tru instance in your application is being initialized more than once, or the `database_url` is being changed after initialization. This is not allowed as per the design of the TruLens library.

Here are some steps you can take to resolve this issue:

1. **Ensure Single Initialization**: Make sure that the Tru instance is only initialized once throughout your application. This error typically occurs if there's an attempt to reinitialize or change the database URL of an already initialized Tru instance. Look for any code that creates multiple instances of the Tru class and consolidate them into a single initialization point.

2. **Review Configuration Logic**: Check your application's logic for setting the `database_url` or `database_file`. Ensure that these parameters are set before the Tru instance is initialized and are not being changed afterward.

3. **Use Singleton Pattern**: If your application architecture requires the Tru instance to be accessed from multiple places, consider implementing the Singleton design pattern for the Tru class. This ensures that only one instance of the Tru class is created and used throughout your application. Here's a simple example of how you might implement this:

```python
class Tru:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super(Tru, cls).__new__(cls)
            # Initialize your instance here
        return cls._instance

    # Your existing methods here
```

4. **Check for Concurrent Access**: If your application involves concurrent execution or multi-threading, ensure that the Tru instance is not being initialized by multiple threads concurrently. Use thread synchronization mechanisms, such as locks, to prevent concurrent initialization.

5. **Debugging**: Add logging around the initialization code to trace the flow of your application and identify where the Tru instance is being initialized or where the database URL is being changed. This can help pinpoint the source of the error.

6. **Review Documentation and Updates**: Check the official documentation of the TruLens repository for any guidelines or updates related to the initialization of the Tru instance. There might be specific instructions or updates that address this issue.

The error message you're seeing is generated by this line of code in the TruLens codebase:

```py
logger.warning(
    "Tru was already initialized. "
    "Cannot change database_url=%s "
    "or database_file=%s .", database_url, database_file
)
```

This is located in the `Tru` class in the `trulens_eval/trulens_eval/tru.py` file. The Tru instance is initialized in the `test_init` method of the `TestTru` class, which is invoked with `Tru(**args)`.

I hope this helps! If you need further assistance, please provide more details about your application's architecture and how you're using the Tru instance.

## Sources
- [trulens_eval/trulens_eval/tru.py](https://github.com/truera/trulens/blob/main/trulens_eval/trulens_eval/tru.py)
- [trulens_eval/tests/e2e/test_tru.py](https://github.com/truera/trulens/blob/main/trulens_eval/tests/e2e/test_tru.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>

This warning gets printed if you try to repeatedly create the `Tru` object. Can you include all the specifications needed the first time you create it?

Closing as this behavior is expected (Tru is a singleton). Please set the url the first time Tru is initialized. If you have additional requirements that make this not possible, please let us know.