3535log = logging .getLogger ("elasticsearch_init" )
3636
3737
38- def wait_for_elasticsearch (host_endpoint : str , interval : float = 1.0 ) -> None :
39- """ Waits until Elasticsearch /_cluster/health returns 200. """
38+ def wait_for_elasticsearch (host_endpoint : str , timeout : int , interval : float = 1.0 ) -> None :
39+ """Waits until Elasticsearch /_cluster/health returns 200."""
4040 health_url = f"{ host_endpoint .rstrip ('/' )} /_cluster/health"
4141
4242 log .info ("Waiting for Elasticsearch at %s ..." , health_url )
4343
44- for attempt in range (DEFAULT_TIMEOUT ):
44+ for attempt in range (timeout ):
4545 try :
46- response = requests .get (health_url , timeout = DEFAULT_TIMEOUT )
46+ response = requests .get (health_url , timeout = timeout )
4747 if response .ok :
4848 log .info ("Elasticsearch is ready (attempt %d)" , attempt + 1 )
4949 return
5050 except requests .RequestException :
5151 pass
52- log .debug (" ...still waiting (%d/%d)" , attempt + 1 , DEFAULT_TIMEOUT )
52+ log .debug (" ...still waiting (%d/%d)" , attempt + 1 , timeout )
5353 time .sleep (interval )
54- raise RuntimeError (f"Elasticsearch did not become ready after { DEFAULT_TIMEOUT } seconds: { health_url } " )
54+ raise RuntimeError (f"Elasticsearch did not become ready after { timeout } seconds: { health_url } " )
5555
5656
57- def create_index (index_endpoint : str ) -> None :
58- """ Creates index """
57+ def create_index (index_endpoint : str , timeout : int ) -> None :
58+ """Creates index if doesn't exist else skips """
5959 try :
60- if requests .head (index_endpoint , timeout = DEFAULT_TIMEOUT ).ok :
60+ if requests .head (index_endpoint , timeout = timeout ).ok :
6161 log .info ("Index already exists at %s. Skipping creation." , index_endpoint )
6262 return
6363 except requests .RequestException :
6464 pass
6565
66- payload = {
67- "settings" : {
68- "index" : {
69- "number_of_shards" : 1 ,
70- "number_of_replicas" : 0
71- }
72- }
73- }
66+ payload = {"settings" : {"index" : {"number_of_shards" : 1 , "number_of_replicas" : 0 }}}
7467
7568 log .info ("Creating index at %s ..." , index_endpoint )
7669 try :
77- response = requests .put (index_endpoint , json = payload , timeout = DEFAULT_TIMEOUT )
70+ response = requests .put (index_endpoint , json = payload , timeout = timeout )
7871 response .raise_for_status ()
7972 log .info ("Index created successfully, %s" , index_endpoint )
8073 except requests .RequestException as e :
8174 log .error ("Failed to create index: %s" , e )
8275 raise
8376
8477
85- def get_count (index_endpoint : str ) -> int :
78+ def get_count (index_endpoint : str , timeout : int ) -> int :
8679 """Returns count from Elasticsearch /_count endpoint or 0 in case of exception."""
8780 count_url = f"{ index_endpoint .rstrip ('/' )} /_count"
81+
8882 params : dict [str , Any ] = {"q" : "*:*" }
8983 try :
90- response = requests .get (count_url , params = params , timeout = DEFAULT_TIMEOUT )
84+ response = requests .get (count_url , params = params , timeout = timeout )
9185 response .raise_for_status ()
9286 body = response .json ()
9387 return int (body .get ("count" , 0 ))
@@ -97,7 +91,7 @@ def get_count(index_endpoint: str) -> int:
9791
9892
9993def load_dataset_to_dict (path : str ) -> list [dict [str , Any ]]:
100- """Loads dataset from jsonl file to dict (no embeddings). """
94+ """Loads dataset from jsonl file to dict (no embeddings)."""
10195 p = Path (path )
10296 if not p .exists ():
10397 raise FileNotFoundError (f"Dataset file is not found: { path } " )
@@ -166,7 +160,7 @@ def merge_docs_with_embeddings(docs: list[dict[str, Any]], embeddings: dict[str,
166160 return merged
167161
168162
169- def get_embedding_dimension_size (embeddings : dict [str , list [float ]]) -> Optional [int ]:
163+ def get_embedding_dimension (embeddings : dict [str , list [float ]]) -> Optional [int ]:
170164 """Returns embedding dimension size or None."""
171165 if not embeddings :
172166 return None
@@ -175,8 +169,8 @@ def get_embedding_dimension_size(embeddings: dict[str, list[float]]) -> Optional
175169 return len (first )
176170
177171
178- def create_vector_field (index_endpoint : str , dimension : int ) -> None :
179- """ Sends PUT to /_mapping to add a 'vector' field with type dense_vector """
172+ def create_vector_field (index_endpoint : str , dimension : int , timeout : int ) -> None :
173+ """Sends PUT to /_mapping to add a 'vector' field with type dense_vector"""
180174 mapping_url = f"{ index_endpoint .rstrip ('/' )} /_mapping"
181175
182176 payload = {
@@ -185,30 +179,28 @@ def create_vector_field(index_endpoint: str, dimension: int) -> None:
185179 "type" : "dense_vector" ,
186180 "dims" : dimension ,
187181 "index" : True ,
188- "similarity" : "cosine"
182+ "similarity" : "cosine" ,
189183 }
190184 }
191185 }
192186
193187 log .info ("Creating dense_vector field (dimension=%d) at %s" , dimension , mapping_url )
194188 try :
195- response = requests .put (mapping_url , json = payload , timeout = DEFAULT_TIMEOUT )
196-
189+ response = requests .put (mapping_url , json = payload , timeout = timeout )
197190 if response .status_code >= 400 :
198191 log .error ("Failed to update mapping. Status: %s, Body: %s" ,
199192 response .status_code , response .text )
200193 return
201194
202195 log .info ("Mapping updated successfully (status=%s)" , response .status_code )
203-
204196 except requests .RequestException as e :
205197 log .error ("Failed to update mapping: %s" , e )
206198 raise
207199 return
208200
209201
210- def index_documents (host_endpoint : str , index_name : str , docs : list [dict [str , Any ]]) -> None :
211- """ Sends documents to Elasticsearch using /_bulk endpoint in batches. """
202+ def index_documents (host_endpoint : str , index_name : str , docs : list [dict [str , Any ]], timeout : int ) -> None :
203+ """Sends documents to Elasticsearch using /_bulk endpoint in batches."""
212204 total_docs = len (docs )
213205 if total_docs == 0 :
214206 log .info ("No documents provided for indexing." )
@@ -230,27 +222,21 @@ def index_documents(host_endpoint: str, index_name: str, docs: list[dict[str, An
230222
231223 body_lines = []
232224 for doc in batch :
233- action_metadata = {"index" : {"_index" : index_name }}
234-
235- if 'id' in doc :
236- action_metadata ["index" ]["_id" ] = str (doc .pop ('id' ))
225+ metadata = {"index" : {"_index" : index_name }}
237226
238- body_lines .append (json .dumps (action_metadata ))
227+ if "id" in doc :
228+ metadata ["index" ]["_id" ] = str (doc .pop ("id" ))
239229
230+ body_lines .append (json .dumps (metadata ))
240231 body_lines .append (json .dumps (doc ))
241232
242233 payload = "\n " .join (body_lines ) + "\n "
243234
244235 log .info (f"Sending Batch { i + 1 } /{ num_batches } ({ len (batch )} docs)" )
245236
246237 try :
247- headers = {'Content-Type' : 'application/x-ndjson' }
248- response = requests .post (
249- bulk_url ,
250- data = payload ,
251- headers = headers ,
252- timeout = DEFAULT_TIMEOUT
253- )
238+ headers = {"Content-Type" : "application/x-ndjson" }
239+ response = requests .post (bulk_url , data = payload , headers = headers , timeout = timeout )
254240 response .raise_for_status ()
255241
256242 log .debug (f"Batch { i + 1 } indexing successful (status={ response .status_code } )" )
@@ -259,38 +245,41 @@ def index_documents(host_endpoint: str, index_name: str, docs: list[dict[str, An
259245 log .error (f"Failed to index batch { i + 1 } : { e } " )
260246 raise Exception (f"Failed during batch { i + 1 } indexing." ) from e
261247
262- log .info ("Successfully indexed %d documents in %d batches." , total_docs , num_batches )
248+ log .info (
249+ "Successfully indexed %d documents in %d batches." , total_docs , num_batches
250+ )
263251
264252
265253def main () -> int :
266254 log .info ("Starting elasticsearch_init.py" )
267255 try :
268- wait_for_elasticsearch (HOST_ENDPOINT , interval = 1.0 )
256+ wait_for_elasticsearch (host_endpoint = HOST_ENDPOINT , timeout = DEFAULT_TIMEOUT , interval = 1.0 )
269257 except Exception as e :
270258 log .error ("Elasticsearch is not available: %s" , e )
271259 sys .exit (1 )
272- create_index (INDEX_ENDPOINT )
273- count_docs = get_count (INDEX_ENDPOINT )
260+ create_index (index_endpoint = INDEX_ENDPOINT , timeout = DEFAULT_TIMEOUT )
261+ count_docs = get_count (index_endpoint = INDEX_ENDPOINT , timeout = DEFAULT_TIMEOUT )
274262 log .info ("Elasticsearch has count = %d docs" , count_docs )
275263
276264 if count_docs == 0 or FORCE_REINDEX :
277265 docs = load_dataset_to_dict (DATASET )
278266 embeddings = load_embeddings_to_dict (EMBEDDINGS_FILE )
279267
280268 if embeddings :
281- embedding_dimension_size = get_embedding_dimension_size (embeddings )
282- if embedding_dimension_size is None :
269+ embedding_dimension = get_embedding_dimension (embeddings )
270+ if embedding_dimension is None :
283271 log .error ("No valid embeddings detected; aborting embedding merge" )
284272 sys .exit (1 )
285- log .info ("Detected embedding dimension = %d" , embedding_dimension_size )
273+ log .info ("Detected embedding dimension = %d" , embedding_dimension )
286274
287275 merged_docs = merge_docs_with_embeddings (docs , embeddings , output_path = TMP_FILE )
288- create_vector_field (INDEX_ENDPOINT , embedding_dimension_size )
276+ create_vector_field (index_endpoint = INDEX_ENDPOINT , dimension = embedding_dimension , timeout = DEFAULT_TIMEOUT )
289277
290- index_documents (HOST_ENDPOINT , INDEX_NAME , merged_docs )
278+ index_documents (host_endpoint = HOST_ENDPOINT ,index_name = INDEX_NAME ,
279+ docs = merged_docs ,timeout = DEFAULT_TIMEOUT )
291280 else :
292281 log .info ("Using plain dataset without embeddings" )
293- index_documents (HOST_ENDPOINT , INDEX_NAME , docs )
282+ index_documents (host_endpoint = HOST_ENDPOINT , index_name = INDEX_NAME , docs = docs , timeout = DEFAULT_TIMEOUT )
294283 Path (TMP_FILE ).unlink (missing_ok = True )
295284 else :
296285 log .info ("Skipping indexing as there are already docs indexed. Use FORCE_REINDEX=true to force re-indexing" )
0 commit comments