here's my code:

import glob
import json
import logging
import os
from collections import namedtuple

#import mxnet as mx

import pandas as pd
import numpy as np
from joblib import load

# from lsh_model import LSH
# from lsh_model import rank_top_similar_items

from sklearn.random_projection import SparseRandomProjection
from sklearn.metrics.pairwise import cosine_similarity
import time

class LSH:
    def __init__(self, n_components, n_hashes):
        
        # Dimensionalty of projected data
        self.n_components = n_components
        
        # number of buckets
        self.n_hashes = n_hashes
        
        # https://scikit-learn.org/stable/modules/generated/sklearn.random_projection.SparseRandomProjection.html
        self.hash_tables = [SparseRandomProjection(n_components=n_components) for _ in range(n_hashes)]

    def fit(self, data):
        if isinstance(data, pd.DataFrame):
            self.item_ids = data.index.tolist()
            data = data.values
        else:
            self.item_ids = np.arange(len(data))
        
        # initialize the hash buckets
        self.hash_buckets = [{} for _ in range(self.n_hashes)]
        for i, hash_table in enumerate(self.hash_tables):
            # For each hash table the function applies SparseRandomProjection. 
            # This step reduce the dimentionality of the data while tryigng to preserve the relative distance between points.
            # Purpose: approximate high-dimentional to low-dimensional data and similar items stays together.
            projections = hash_table.fit_transform(data)
            for j, projection in enumerate(projections):
                # After projecting data for each hash table, the funtion iterates over these projections.
                # For each data points projection, it creates a hash key. The key is generate by the sign of each component.
                # The idea is if two points are close in high-dimensional space, their projections must also be closed.
                # Ex projection: [ 0.72199595 -0.6867862  -0.5098184   0.55619763  4.24497602  1.08506354
                # -2.26010595 -2.79241899  6.01301565 -4.82428779  1.05509869 -2.29027826
                # -2.13740946  1.06065566 -1.57524544  0.58627834]
                # Ex hash_key: (1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1)
                hash_key = tuple(np.where(projection > 0, 1, 0))
                if hash_key not in self.hash_buckets[i]:
                    # Create the item with the hash_key
                    self.hash_buckets[i][hash_key] = []
                
                # Append to that specific hash_bucket, j, with the unique and shared hash_key 
                self.hash_buckets[i][hash_key].append(j)
        return self.hash_buckets

    def query(self, point):
        if isinstance(point, pd.Series):
            point = point.to_numpy().reshape(1, -1)  # Correct way to handle Series
        elif isinstance(point, np.ndarray):
            point = point.reshape(1, -1)
        
        # To eliminate the chance of duplicates
        similar_items = set()
        for i, hash_table in enumerate(self.hash_tables):
            projection = hash_table.transform(point)
            hash_key = tuple(np.where(projection > 0, 1, 0)[0])
            similar_items.update(self.hash_buckets[i].get(hash_key, []))

        similar_item_ids = [self.item_ids[i] for i in similar_items]
        return similar_item_ids

def rank_top_similar_items(data, query_input, similar_inputs, top_n=10):
    if isinstance(data, pd.DataFrame):
        query_item = data.loc[query_input].values.reshape(1, -1)
    else:
        query_item = data[query_input].reshape(1, -1)

    similarities = []
    for input_ in similar_inputs:
        if input_ != query_input:
            if isinstance(data, pd.DataFrame):
                item = data.loc[input_].values.reshape(1, -1)
            else:
                item = data[input_].reshape(1, -1)
            similarity_score = cosine_similarity(query_item, item)[0][0]
            similarities.append((input_, similarity_score))

    sorted_similarities = sorted(similarities, key=lambda x: x[1], reverse=True)
    top_similar_indices = [item[0] for item in sorted_similarities[:top_n]]
    return top_similar_indices

class ModelHandler(object):
    
    def __init__(self):
        self.initialized = False
        self.lsh_model = None

    def initialize(self, context):
        self.initialized = True
        print(context)
        properties = context.system_properties
        model_dir = properties.get("model_dir")
        print("model directory",model_dir)
        #model_name = properties.get("model_name")  #this doesnt work currently
        print(os.listdir(path=model_dir))
        model_name = "lsh_model_tongue_lining"
        print("model name",model_name)
        #model_path = model_dir +"/"+ model_name
        model_path = "/opt/ml/model/lsh_model_tongue_lining.joblib"
        data_path = "/opt/ml/model/lsh_model_tongue_lining.pkl"
        self.lsh_model_loaded = load(model_path)
        print("loaded the lsh model")
        self.model_data = pd.read_pickle(data_path)
        print("loaded the model data")

        #return self.lsh_model_loaded, self.model_data
        

    def inference(self, model, data, query_id, top_n=20):

        # Find similar IDs and rank them
        similar_ids = model.query(data.loc[query_id])
        top_n_similar_ids = rank_top_similar_items(data, query_id, similar_ids, top_n=top_n)
   
        return top_n_similar_ids
    

    def handle(self, data, context):

        logging.info(data)
        logging.info(context)
        # input_data = json.loads(data)
        # if "test" not in input_data:
        #     raise ValueError("Input data does not contain the key 'test'")
        # test_value = input_data["test"]
        print("loading the insference function for recommendations")
        recommendations = self.inference(self.lsh_model_loaded, self.model_data, data["query_id"], top_n=20)
        print("generating recommendations",recommendations)
        # Perform some computation
        #result = "hello world!"

        # Create the output JSON
        #output_data = {"result": result}

        # Convert the output JSON to string
        #output_json = json.dumps(output_data)

        return [[recommendations]]


_service = ModelHandler()


def handle(data, context):
    if not _service.initialized:
        _service.initialize(context)

    if data is None:
        return None
    
    #result = "hello world!"

    # Create the output JSON
    #output_data = {"result": result}

    # Convert the output JSON to string
    #output_json = json.dumps(output_data)
    #return {"message": "Hello, World!"}
    print("return output _service.handle(data, context)",_service.handle(data, context))
    return _service.handle(data, context)

---

Can yo utake class LSH inside class ModelHandler(object)?