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

[FEAT]: Support redis hosting for 4 database on cloud #428

Open
lwaekfjlk opened this issue Jul 21, 2024 · 6 comments
Open

[FEAT]: Support redis hosting for 4 database on cloud #428

lwaekfjlk opened this issue Jul 21, 2024 · 6 comments
Assignees
Labels
enhancement New feature or request
Milestone

Comments

@lwaekfjlk
Copy link
Member

Description

with real backend

Additional Information

No response

@lwaekfjlk lwaekfjlk added the enhancement New feature or request label Jul 21, 2024
@lwaekfjlk lwaekfjlk changed the title [FEAT]: Support redis hosting for 4 database [FEAT]: Support redis hosting for 4 database on cloud Jul 21, 2024
@lwaekfjlk lwaekfjlk added this to the 0.0.2 release milestone Jul 21, 2024
@shreypandey
Copy link
Contributor

shreypandey commented Oct 12, 2024

Hi @lwaekfjlk,
For redis support, a multi container app can be created using docker-compose with the support of local development. The following 3 container will be there:

  1. backend
  2. frontend
  3. redis

image

A bash script can be created which will abstract the logic of running of the multi container app from the users. Something like this:

# set env variables and config
docker compose --env-file "$env_file" build
docker compose --env-file "$env_file" up

Users just need to run the following command to run the project in their local. This will make easier for users to run and develop the project.

bash run.sh

For handling the scenario where the user want to run the example sdk using a python script(as mentioned in running example of readme.md), support of on-memory and redis database client can be provided, picking up the appropriate database using config/env variable.
This is an pseudo implementation of handling redis as well as currently supported on-memory storage.

class DatabaseClient(ABC):
    @abstractmethod 
    def add(self, data: T) -> None:
        
    @abstractmethod
    def update(self, pk: str, updates: Dict[str, Any]) -> bool:
        
    @abstractmethod
    def delete(self, pk: str) -> bool:
        
    @abstractmethod
    def get(self, **conditions: Union[str, int, float, List[int], None]) -> List[T]:

    @abstractmethod
    def search(self, query_embedding: np.ndarray, **conditions: Union[str, int, float, List[int], None]):    # Types can be revised later
        
class LocalDatabaseClient(DatabaseClient):
    # Concrete implementation of the LocalDatabaseProvider. 
    # In this case, it will mostly be replicated from existing BaseDB class 

class RedisDatabaseClient():
    __redis_client__: redis.Redis = None # For singleton connection to redis
    
    @classmethod
    def create_client(cls):
        if cls.__redis_client__ is None:
            cls.__redis_client__ = cls.create_redis_client() # Initialize redis SDK here
    
    # Concrete implementation of abstract methods according to redis client SDK

DATABASE_REGISTRY: Dict[str, Type[DatabaseClient]] = {
    "redis": RedisDatabaseClient,
    "local": LocalDatabaseClient
}

class DatabaseClientHandler:
    __database_client__: DatabaseClient = None # For singleton client
     
    @classmethod
    def get_instance(cls) -> DatabaseClient:
        if cls.__database_client__ is None:
            database_type = os.getenv("database_type", "local") # This can be from config also
            if not database_type in DATABASE_REGISTRY:
                raise Exception("Invalid database type")
            cls.__database_client__ = DATABASE_REGISTRY.get(database_type)()
            return cls.__database_client__

The BaseDB will look something like this:

class BaseDB(Generic[T]):
    def __init__(
        self, data_class: Type[T], load_file_path: Optional[str] = None
    ) -> None:
        self.project_name: Optional[str] = None
        self.data_class = data_class
        # data, embeddings and load_from_json should be handled in appropriate DatabaseClient
        self.data_base_client = DatabaseClientHandler.get_instance()
        
    def set_project_name(self, project_name: str) -> None:
        self.project_name = project_name

    def add(self, data: T) -> None:
        if self.project_name is not None:
            data.project_name = self.project_name
        self.data_base_client.add(data)
        logger.info(
            f"Creating instance of '{data.__class__.__name__}': '{data.model_dump()}'"
        )
.
.
.

Let me know your thoughts on this.

@lwaekfjlk
Copy link
Member Author

that's perfect! We should implement this. I can try to make one initial PR asap. Thanks a lot for your suggestions.

@lwaekfjlk
Copy link
Member Author

@shreypandey feel free to create a PR to share any progress so that we can work together to make this feature.

@robotMonkeyButler robotMonkeyButler pinned this issue Oct 13, 2024
@shreypandey
Copy link
Contributor

@lwaekfjlk I will create a PR on this. You can assign this issue to me if you want.

@lwaekfjlk
Copy link
Member Author

that's awesome!!!

@lwaekfjlk
Copy link
Member Author

looking forward to this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants