From 8396facf84e1d57aa795cf18e84443a79bb28627 Mon Sep 17 00:00:00 2001 From: niebayes Date: Mon, 22 Dec 2025 08:16:10 +0000 Subject: [PATCH 1/2] fix typos and add typo check --- .github/workflows/pull_request.yml | 4 +++ Makefile | 3 ++ tests/test_chroma.py | 4 +-- typos.toml | 3 ++ .../backend/clients/alisql/alisql.py | 2 +- .../aliyun_opensearch/aliyun_opensearch.py | 2 +- vectordb_bench/backend/clients/api.py | 6 ++-- .../backend/clients/chroma/chroma.py | 2 +- .../backend/clients/clickhouse/clickhouse.py | 4 +-- vectordb_bench/backend/clients/doris/doris.py | 2 +- .../backend/clients/mariadb/mariadb.py | 2 +- .../backend/clients/memorydb/memorydb.py | 2 +- .../backend/clients/milvus/milvus.py | 6 ++-- .../backend/clients/pgvecto_rs/config.py | 6 ++-- .../backend/clients/pinecone/pinecone.py | 6 ++-- vectordb_bench/backend/clients/redis/redis.py | 2 +- .../backend/clients/s3_vectors/s3_vectors.py | 2 +- vectordb_bench/backend/clients/vespa/vespa.py | 4 +-- vectordb_bench/backend/runner/mp_runner.py | 2 +- .../backend/runner/read_write_runner.py | 6 ++-- vectordb_bench/backend/utils.py | 14 +++++----- vectordb_bench/custom/custom_case.json | 2 +- .../components/check_results/filters.py | 18 ++++++------ .../frontend/components/check_results/nav.py | 8 +++--- .../components/custom/displayCustomCase.py | 4 +-- .../components/custom/getCustomConfig.py | 2 +- .../components/run_test/caseSelector.py | 28 +++++++++---------- .../components/run_test/dbConfigSetting.py | 4 +-- .../components/run_test/dbSelector.py | 8 +++--- .../components/run_test/generateTasks.py | 6 ++-- .../components/welcome/welcomePrams.py | 14 +++++----- .../frontend/config/dbCaseConfigs.py | 4 +-- vectordb_bench/frontend/pages/int_filter.py | 6 ++-- vectordb_bench/frontend/pages/label_filter.py | 6 ++-- vectordb_bench/frontend/pages/qps_recall.py | 6 ++-- ...es_per_dollar.py => queries_per_dollar.py} | 4 +-- vectordb_bench/frontend/pages/results.py | 6 ++-- vectordb_bench/frontend/pages/run_test.py | 10 +++---- vectordb_bench/interface.py | 6 ++-- vectordb_bench/log_util.py | 17 ++++++----- vectordb_bench/metric.py | 6 ++-- vectordb_bench/models.py | 2 +- 42 files changed, 130 insertions(+), 121 deletions(-) create mode 100644 typos.toml rename vectordb_bench/frontend/pages/{quries_per_dollar.py => queries_per_dollar.py} (95%) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index e9de2c3b9..05e0ac46a 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -31,6 +31,10 @@ jobs: run: | python -m pip install --upgrade pip pip install -e ".[test]" + pip install codespell + + - name: Run typo checks + uses: crate-ci/typos@v1.40.0 - name: Run coding checks run: | diff --git a/Makefile b/Makefile index ef8207c55..5bf39b8a8 100644 --- a/Makefile +++ b/Makefile @@ -8,3 +8,6 @@ format: lint: PYTHONPATH=`pwd` python3 -m black vectordb_bench --check PYTHONPATH=`pwd` python3 -m ruff check vectordb_bench + +typos: + typos README.md install.py vectordb_bench tests diff --git a/tests/test_chroma.py b/tests/test_chroma.py index 2b1b0596e..29cb4956f 100644 --- a/tests/test_chroma.py +++ b/tests/test_chroma.py @@ -20,7 +20,7 @@ -dict = {} #Assumes chroma is acception connections on localhost:8000 +dict = {} # Assumes chroma is accepting connections on localhost:8000 dict['name'] = "chroma" dict['host'] = "localhost" dict['port'] = 8000 @@ -102,4 +102,4 @@ def test_insert_and_search(self): break assert isFilter, f"Filter not working, id_list: {id_list}" - \ No newline at end of file + diff --git a/typos.toml b/typos.toml new file mode 100644 index 000000000..578d2b41d --- /dev/null +++ b/typos.toml @@ -0,0 +1,3 @@ +[default.extend-words] +# Respect RaBit, RaBitQ as correct spelling. +"rabit" = "rabit" diff --git a/vectordb_bench/backend/clients/alisql/alisql.py b/vectordb_bench/backend/clients/alisql/alisql.py index 76179c2ed..549ff3320 100644 --- a/vectordb_bench/backend/clients/alisql/alisql.py +++ b/vectordb_bench/backend/clients/alisql/alisql.py @@ -91,7 +91,7 @@ def _create_db_table(self, dim: int): @contextmanager def init(self): - """create and destory connections to database. + """create and destroy connections to database. Examples: >>> with self.init(): diff --git a/vectordb_bench/backend/clients/aliyun_opensearch/aliyun_opensearch.py b/vectordb_bench/backend/clients/aliyun_opensearch/aliyun_opensearch.py index 138e10bba..3aba33328 100644 --- a/vectordb_bench/backend/clients/aliyun_opensearch/aliyun_opensearch.py +++ b/vectordb_bench/backend/clients/aliyun_opensearch/aliyun_opensearch.py @@ -310,7 +310,7 @@ def search_embedding( return [one_res["id"] for one_res in res["result"]] def need_normalize_cosine(self) -> bool: - """Wheather this database need to normalize dataset to support COSINE""" + """Whether this database need to normalize dataset to support COSINE""" if self.case_config.metric_type == MetricType.COSINE: log.info("cosine dataset need normalize.") return True diff --git a/vectordb_bench/backend/clients/api.py b/vectordb_bench/backend/clients/api.py index 605e85ac0..b67ee1bff 100644 --- a/vectordb_bench/backend/clients/api.py +++ b/vectordb_bench/backend/clients/api.py @@ -97,7 +97,7 @@ def not_empty_field(cls, v: any, field: any): class DBCaseConfig(ABC): - """Case specific vector database configs, usually uesed for index params like HNSW""" + """Case specific vector database configs, usually used for index params like HNSW""" @abstractmethod def index_param(self) -> dict: @@ -176,7 +176,7 @@ def __init__( @abstractmethod @contextmanager def init(self) -> None: - """create and destory connections to database. + """create and destroy connections to database. Why contextmanager: In multiprocessing search tasks, vectordbbench might init @@ -192,7 +192,7 @@ def init(self) -> None: raise NotImplementedError def need_normalize_cosine(self) -> bool: - """Wheather this database need to normalize dataset to support COSINE""" + """Whether this database need to normalize dataset to support COSINE""" return False @abstractmethod diff --git a/vectordb_bench/backend/clients/chroma/chroma.py b/vectordb_bench/backend/clients/chroma/chroma.py index 7f2cd2f1c..47beb72e7 100644 --- a/vectordb_bench/backend/clients/chroma/chroma.py +++ b/vectordb_bench/backend/clients/chroma/chroma.py @@ -40,7 +40,7 @@ def __init__( @contextmanager def init(self) -> None: - """create and destory connections to database. + """create and destroy connections to database. Examples: >>> with self.init(): diff --git a/vectordb_bench/backend/clients/clickhouse/clickhouse.py b/vectordb_bench/backend/clients/clickhouse/clickhouse.py index de09895a8..860144344 100644 --- a/vectordb_bench/backend/clients/clickhouse/clickhouse.py +++ b/vectordb_bench/backend/clients/clickhouse/clickhouse.py @@ -91,7 +91,7 @@ def _drop_table(self): log.warning(f"Failed to drop table {self.db_config['database']}.{self.table_name}: {e}") raise e from None - def _perfomance_tuning(self): + def _performance_tuning(self): self.conn.command("SET materialize_skip_indexes_on_insert = 1") def _create_index(self): @@ -120,7 +120,7 @@ def _create_index(self): """ self.conn.command(cmd=query) else: - log.warning("HNSW is only avaliable method in clickhouse now") + log.warning("HNSW is only available method in clickhouse now") except Exception as e: log.warning(f"Failed to create Clickhouse vector index on table: {self.table_name} error: {e}") raise e from None diff --git a/vectordb_bench/backend/clients/doris/doris.py b/vectordb_bench/backend/clients/doris/doris.py index 82b3a12da..4aebe2b72 100644 --- a/vectordb_bench/backend/clients/doris/doris.py +++ b/vectordb_bench/backend/clients/doris/doris.py @@ -234,7 +234,7 @@ def optimize(self, data_size: int | None = None) -> None: log.info("Optimization completed using doris-vector-search library") def need_normalize_cosine(self) -> bool: - """Wheather this database need to normalize dataset to support COSINE""" + """Whether this database need to normalize dataset to support COSINE""" if self.case_config.metric_type == MetricType.COSINE: log.info("cosine dataset need normalize.") return True diff --git a/vectordb_bench/backend/clients/mariadb/mariadb.py b/vectordb_bench/backend/clients/mariadb/mariadb.py index 5ccddfe7a..e1698162a 100644 --- a/vectordb_bench/backend/clients/mariadb/mariadb.py +++ b/vectordb_bench/backend/clients/mariadb/mariadb.py @@ -89,7 +89,7 @@ def _create_db_table(self, dim: int): @contextmanager def init(self): - """create and destory connections to database. + """create and destroy connections to database. Examples: >>> with self.init(): diff --git a/vectordb_bench/backend/clients/memorydb/memorydb.py b/vectordb_bench/backend/clients/memorydb/memorydb.py index 7e7a8650b..d7bea957b 100644 --- a/vectordb_bench/backend/clients/memorydb/memorydb.py +++ b/vectordb_bench/backend/clients/memorydb/memorydb.py @@ -148,7 +148,7 @@ def get_client(self, **kwargs): @contextmanager def init(self) -> Generator[None, None, None]: - """create and destory connections to database. + """create and destroy connections to database. Examples: >>> with self.init(): diff --git a/vectordb_bench/backend/clients/milvus/milvus.py b/vectordb_bench/backend/clients/milvus/milvus.py index b177af332..aca6c45fe 100644 --- a/vectordb_bench/backend/clients/milvus/milvus.py +++ b/vectordb_bench/backend/clients/milvus/milvus.py @@ -135,7 +135,7 @@ def init(self): self.col: Collection | None = None connections.connect(**self.db_config, timeout=60) - # Grab the existing colection with connections + # Grab the existing collection with connections self.col = Collection(self.collection_name) yield @@ -174,7 +174,7 @@ def wait_index(): try: self.col.compact() self.col.wait_for_compaction_completed() - log.info("compactation completed. waiting for the rest of index buliding.") + log.info("compactation completed. waiting for the rest of index building.") except Exception as e: log.warning(f"{self.name} compact error: {e}") if hasattr(e, "code"): @@ -192,7 +192,7 @@ def optimize(self, data_size: int | None = None): self._optimize() def need_normalize_cosine(self) -> bool: - """Wheather this database need to normalize dataset to support COSINE""" + """Whether this database need to normalize dataset to support COSINE""" if self.case_config.is_gpu_index: log.info("current gpu_index only supports IP / L2, cosine dataset need normalize.") return True diff --git a/vectordb_bench/backend/clients/pgvecto_rs/config.py b/vectordb_bench/backend/clients/pgvecto_rs/config.py index fbb7c5d81..37570b0b6 100644 --- a/vectordb_bench/backend/clients/pgvecto_rs/config.py +++ b/vectordb_bench/backend/clients/pgvecto_rs/config.py @@ -85,7 +85,7 @@ def index_param(self) -> dict[str, str]: if self.quantization_type is None: quantization = None else: - quantization = Quantization(typ=self.quantization_type, ratio=self.quantization_ratio) + quantization = Quantization(type=self.quantization_type, ratio=self.quantization_ratio) option = IndexOption( index=Hnsw( @@ -113,7 +113,7 @@ def index_param(self) -> dict[str, str]: if self.quantization_type is None: quantization = None else: - quantization = Quantization(typ=self.quantization_type, ratio=self.quantization_ratio) + quantization = Quantization(type=self.quantization_type, ratio=self.quantization_ratio) option = IndexOption( index=Ivf(nlist=self.lists, quantization=quantization), @@ -135,7 +135,7 @@ def index_param(self) -> dict[str, str]: if self.quantization_type is None: quantization = None else: - quantization = Quantization(typ=self.quantization_type, ratio=self.quantization_ratio) + quantization = Quantization(type=self.quantization_type, ratio=self.quantization_ratio) option = IndexOption( index=Flat( diff --git a/vectordb_bench/backend/clients/pinecone/pinecone.py b/vectordb_bench/backend/clients/pinecone/pinecone.py index 9c2b38888..e7ceffc47 100644 --- a/vectordb_bench/backend/clients/pinecone/pinecone.py +++ b/vectordb_bench/backend/clients/pinecone/pinecone.py @@ -76,7 +76,7 @@ def insert_embeddings( try: for batch_start_offset in range(0, len(embeddings), self.batch_size): batch_end_offset = min(batch_start_offset + self.batch_size, len(embeddings)) - insert_datas = [] + insert_batch = [] for i in range(batch_start_offset, batch_end_offset): metadata_dict = {self._scalar_id_field: metadata[i]} if self.with_scalar_labels: @@ -86,8 +86,8 @@ def insert_embeddings( embeddings[i], metadata_dict, ) - insert_datas.append(insert_data) - self.index.upsert(insert_datas) + insert_batch.append(insert_data) + self.index.upsert(insert_batch) insert_count += batch_end_offset - batch_start_offset except Exception as e: return insert_count, e diff --git a/vectordb_bench/backend/clients/redis/redis.py b/vectordb_bench/backend/clients/redis/redis.py index ef0aad9aa..dc778a0d9 100644 --- a/vectordb_bench/backend/clients/redis/redis.py +++ b/vectordb_bench/backend/clients/redis/redis.py @@ -76,7 +76,7 @@ def make_index(self, vector_dimensions: int, conn: redis.Redis): @contextmanager def init(self) -> None: - """create and destory connections to database. + """create and destroy connections to database. Examples: >>> with self.init(): diff --git a/vectordb_bench/backend/clients/s3_vectors/s3_vectors.py b/vectordb_bench/backend/clients/s3_vectors/s3_vectors.py index b05134f6b..09995aafb 100644 --- a/vectordb_bench/backend/clients/s3_vectors/s3_vectors.py +++ b/vectordb_bench/backend/clients/s3_vectors/s3_vectors.py @@ -95,7 +95,7 @@ def optimize(self, **kwargs): return def need_normalize_cosine(self) -> bool: - """Wheather this database need to normalize dataset to support COSINE""" + """Whether this database need to normalize dataset to support COSINE""" return False def insert_embeddings( diff --git a/vectordb_bench/backend/clients/vespa/vespa.py b/vectordb_bench/backend/clients/vespa/vespa.py index 5288bc04c..dedd9b42e 100644 --- a/vectordb_bench/backend/clients/vespa/vespa.py +++ b/vectordb_bench/backend/clients/vespa/vespa.py @@ -40,7 +40,7 @@ def __init__( @contextmanager def init(self) -> Generator[None, None, None]: - """create and destory connections to database. + """create and destroy connections to database. Why contextmanager: In multiprocessing search tasks, vectordbbench might init @@ -58,7 +58,7 @@ def init(self) -> Generator[None, None, None]: self.client = None def need_normalize_cosine(self) -> bool: - """Wheather this database need to normalize dataset to support COSINE""" + """Whether this database need to normalize dataset to support COSINE""" return False def insert_embeddings( diff --git a/vectordb_bench/backend/runner/mp_runner.py b/vectordb_bench/backend/runner/mp_runner.py index 9133e407a..21e31d897 100644 --- a/vectordb_bench/backend/runner/mp_runner.py +++ b/vectordb_bench/backend/runner/mp_runner.py @@ -32,7 +32,7 @@ class MultiProcessingSearchRunner: Args: k(int): search topk, default to 100 concurrency(Iterable): concurrencies, default [1, 5, 10, 15, 20, 25, 30, 35] - duration(int): duration for each concurency, default to 30s + duration(int): duration for each concurrency, default to 30s """ def __init__( diff --git a/vectordb_bench/backend/runner/read_write_runner.py b/vectordb_bench/backend/runner/read_write_runner.py index d3d1df2fa..717e0ee52 100644 --- a/vectordb_bench/backend/runner/read_write_runner.py +++ b/vectordb_bench/backend/runner/read_write_runner.py @@ -88,7 +88,7 @@ def __init__( @time_it def run_optimize(self): - """Optimize needs to run in differenct process for pymilvus schema recursion problem""" + """Optimize needs to run in different process for pymilvus schema recursion problem""" with self.db.init(): log.info("Search after write - Optimize start") self.db.optimize(data_size=self.data_volume) @@ -104,7 +104,7 @@ def run_search(self, perc: int): f"p99={p99_latency}, p95={p95_latency}, dur={ssearch_dur:.4f}", ) log.info( - f"Search after wirte - Conc search start, dur for each conc={self.read_dur_after_write}", + f"Search after write - Conc search start, dur for each conc={self.read_dur_after_write}", ) result = self.run_by_dur(self.read_dur_after_write) max_qps = result[0] @@ -114,7 +114,7 @@ def run_search(self, perc: int): conc_latency_p99_list = result[4] conc_latency_p95_list = result[5] conc_latency_avg_list = result[6] - log.info(f"Search after wirte - Conc search finished, max_qps={max_qps}") + log.info(f"Search after write - Conc search finished, max_qps={max_qps}") return [ ( diff --git a/vectordb_bench/backend/utils.py b/vectordb_bench/backend/utils.py index 86c4faf5e..85dabe811 100644 --- a/vectordb_bench/backend/utils.py +++ b/vectordb_bench/backend/utils.py @@ -11,7 +11,7 @@ def numerize(n: int) -> str: >>> numerize(1_000_000_000) '1B' """ - sufix2upbound = { + suffix2upbound = { "EMPTY": 1e3, "K": 1e6, "M": 1e9, @@ -19,19 +19,19 @@ def numerize(n: int) -> str: "END": float("inf"), } - display_n, sufix = n, "" - for s, base in sufix2upbound.items(): - # number >= 1000B will alway have sufix 'B' + display_n, suffix = n, "" + for s, base in suffix2upbound.items(): + # number >= 1000B will always have suffix 'B' if s == "END": display_n = int(n / 1e9) - sufix = "B" + suffix = "B" break if n < base: - sufix = "" if s == "EMPTY" else s + suffix = "" if s == "EMPTY" else s display_n = int(n / (base / 1e3)) break - return f"{display_n}{sufix}" + return f"{display_n}{suffix}" def time_it(func: any): diff --git a/vectordb_bench/custom/custom_case.json b/vectordb_bench/custom/custom_case.json index 12ca6597b..697c41791 100644 --- a/vectordb_bench/custom/custom_case.json +++ b/vectordb_bench/custom/custom_case.json @@ -1,6 +1,6 @@ [ { - "name": "My Dataset (Performace Case)", + "name": "My Dataset (Performance Case)", "description": "this is a customized dataset.", "load_timeout": 36000, "optimize_timeout": 36000, diff --git a/vectordb_bench/frontend/components/check_results/filters.py b/vectordb_bench/frontend/components/check_results/filters.py index 6016c0040..c92ec1690 100644 --- a/vectordb_bench/frontend/components/check_results/filters.py +++ b/vectordb_bench/frontend/components/check_results/filters.py @@ -98,7 +98,7 @@ def getShowDbsAndCases(st, result: list[CaseResult], filter_type: FilterOp) -> t "Case Filter", datasetWithSizeTypes, col=1, - optionLables=[v.value for v in datasetWithSizeTypes], + optionLabels=[v.value for v in datasetWithSizeTypes], ) datasets = [dataset_with_size_type.get_manager() for dataset_with_size_type in showDatasetWithSizeTypes] showCaseNames = list(set([case.name for case in allCases if case.dataset in datasets])) @@ -106,7 +106,7 @@ def getShowDbsAndCases(st, result: list[CaseResult], filter_type: FilterOp) -> t return showDBNames, showCaseNames -def filterView(container, header, options, col, optionLables=None): +def filterView(container, header, options, col, optionLabels=None): selectAllState = f"{header}-select-all-state" if selectAllState not in st.session_state: st.session_state[selectAllState] = True @@ -137,14 +137,14 @@ def filterView(container, header, options, col, optionLables=None): col, gap="small", ) - if optionLables is None: - optionLables = options - isActive = {option: st.session_state[selectAllState] for option in optionLables} - for i, option in enumerate(optionLables): + if optionLabels is None: + optionLabels = options + isActive = {option: st.session_state[selectAllState] for option in optionLabels} + for i, option in enumerate(optionLabels): isActive[option] = columns[i % col].checkbox( - optionLables[i], + optionLabels[i], value=isActive[option], - key=f"{optionLables[i]}-{st.session_state[countKeyState]}", + key=f"{optionLabels[i]}-{st.session_state[countKeyState]}", ) - return [options[i] for i, option in enumerate(optionLables) if isActive[option]] + return [options[i] for i, option in enumerate(optionLabels) if isActive[option]] diff --git a/vectordb_bench/frontend/components/check_results/nav.py b/vectordb_bench/frontend/components/check_results/nav.py index ba4fa99c7..f1bf08d84 100644 --- a/vectordb_bench/frontend/components/check_results/nav.py +++ b/vectordb_bench/frontend/components/check_results/nav.py @@ -9,11 +9,11 @@ def NavToRunTest(st): switch_page("run test") -def NavToQuriesPerDollar(st): +def NavToQueriesPerDollar(st): st.subheader("Compare qps with price.") - navClick = st.button("QP$ (Quries per Dollar)   >") + navClick = st.button("QP$ (Queries per Dollar)   >") if navClick: - switch_page("quries_per_dollar") + switch_page("queries_per_dollar") def NavToResults(st, key="nav-to-results"): @@ -27,7 +27,7 @@ def NavToPages(st): {"name": "Run Test", "link": "run_test"}, {"name": "Results", "link": "results"}, {"name": "Qps & Recall", "link": "qps_recall"}, - {"name": "Quries Per Dollar", "link": "quries_per_dollar"}, + {"name": "Queries Per Dollar", "link": "queries_per_dollar"}, {"name": "Concurrent", "link": "concurrent"}, {"name": "Label Filter", "link": "label_filter"}, {"name": "Int Filter", "link": "int_filter"}, diff --git a/vectordb_bench/frontend/components/custom/displayCustomCase.py b/vectordb_bench/frontend/components/custom/displayCustomCase.py index 1aa03f96b..e6ac81887 100644 --- a/vectordb_bench/frontend/components/custom/displayCustomCase.py +++ b/vectordb_bench/frontend/components/custom/displayCustomCase.py @@ -7,7 +7,7 @@ def displayCustomCase(customCase: CustomCaseConfig, st, key): customCase.dataset_config.name = columns[0].text_input( "Name", key=f"{key}_name", value=customCase.dataset_config.name ) - customCase.name = f"{customCase.dataset_config.name} (Performace Case)" + customCase.name = f"{customCase.dataset_config.name} (Performance Case)" customCase.dataset_config.dir = columns[1].text_input( "Folder Path", key=f"{key}_dir", value=customCase.dataset_config.dir ) @@ -59,7 +59,7 @@ def displayCustomCase(customCase: CustomCaseConfig, st, key): default_label_percentages = ",".join(map(str, customCase.dataset_config.with_label_percentages)) label_percentage_input = columns[1].text_input( "label percentages", - key=f"{key}_label_percantages", + key=f"{key}_label_percentages", value=default_label_percentages, ) try: diff --git a/vectordb_bench/frontend/components/custom/getCustomConfig.py b/vectordb_bench/frontend/components/custom/getCustomConfig.py index a1ddfb737..c3eb11f9a 100644 --- a/vectordb_bench/frontend/components/custom/getCustomConfig.py +++ b/vectordb_bench/frontend/components/custom/getCustomConfig.py @@ -27,7 +27,7 @@ class CustomDatasetConfig(BaseModel): class CustomCaseConfig(BaseModel): - name: str = "custom_dataset (Performace Case)" + name: str = "custom_dataset (Performance Case)" description: str = "" load_timeout: int = 36000 optimize_timeout: int = 36000 diff --git a/vectordb_bench/frontend/components/run_test/caseSelector.py b/vectordb_bench/frontend/components/run_test/caseSelector.py index 2e104ce54..f4d7d37a3 100644 --- a/vectordb_bench/frontend/components/run_test/caseSelector.py +++ b/vectordb_bench/frontend/components/run_test/caseSelector.py @@ -6,7 +6,7 @@ UICaseItem, UICaseItemCluster, get_case_config_inputs, - get_custom_case_cluter, + get_custom_case_cluster, get_custom_streaming_case_cluster, ) from vectordb_bench.frontend.config.styles import ( @@ -19,7 +19,7 @@ from vectordb_bench.models import CaseConfig -def caseSelector(st, activedDbList: list[DB]): +def caseSelector(st, activeDbList: list[DB]): st.markdown( "
", unsafe_allow_html=True, @@ -30,32 +30,32 @@ def caseSelector(st, activedDbList: list[DB]): unsafe_allow_html=True, ) - activedCaseList: list[CaseConfig] = [] + activeCaseList: list[CaseConfig] = [] dbToCaseClusterConfigs = defaultdict(lambda: defaultdict(dict)) dbToCaseConfigs = defaultdict(lambda: defaultdict(dict)) - caseClusters = UI_CASE_CLUSTERS + [get_custom_case_cluter(), get_custom_streaming_case_cluster()] + caseClusters = UI_CASE_CLUSTERS + [get_custom_case_cluster(), get_custom_streaming_case_cluster()] for caseCluster in caseClusters: - activedCaseList += caseClusterExpander(st, caseCluster, dbToCaseClusterConfigs, activedDbList) + activeCaseList += caseClusterExpander(st, caseCluster, dbToCaseClusterConfigs, activeDbList) for db in dbToCaseClusterConfigs: for uiCaseItem in dbToCaseClusterConfigs[db]: for case in uiCaseItem.get_cases(): dbToCaseConfigs[db][case] = dbToCaseClusterConfigs[db][uiCaseItem] - return activedCaseList, dbToCaseConfigs + return activeCaseList, dbToCaseConfigs -def caseClusterExpander(st, caseCluster: UICaseItemCluster, dbToCaseClusterConfigs, activedDbList: list[DB]): +def caseClusterExpander(st, caseCluster: UICaseItemCluster, dbToCaseClusterConfigs, activeDbList: list[DB]): expander = st.expander(caseCluster.label, False) - activedCases: list[CaseConfig] = [] + activeCases: list[CaseConfig] = [] for uiCaseItem in caseCluster.uiCaseItems: if uiCaseItem.isLine: addHorizontalLine(expander) else: - activedCases += caseItemCheckbox(expander, dbToCaseClusterConfigs, uiCaseItem, activedDbList) - return activedCases + activeCases += caseItemCheckbox(expander, dbToCaseClusterConfigs, uiCaseItem, activeDbList) + return activeCases -def caseItemCheckbox(st, dbToCaseClusterConfigs, uiCaseItem: UICaseItem, activedDbList: list[DB]): +def caseItemCheckbox(st, dbToCaseClusterConfigs, uiCaseItem: UICaseItem, activeDbList: list[DB]): selected = st.checkbox(uiCaseItem.label) st.markdown( f"
{uiCaseItem.description}
", @@ -65,7 +65,7 @@ def caseItemCheckbox(st, dbToCaseClusterConfigs, uiCaseItem: UICaseItem, actived caseConfigSetting(st.container(), uiCaseItem) if selected: - dbCaseConfigSetting(st.container(), dbToCaseClusterConfigs, uiCaseItem, activedDbList) + dbCaseConfigSetting(st.container(), dbToCaseClusterConfigs, uiCaseItem, activeDbList) return uiCaseItem.get_cases() if selected else [] @@ -91,8 +91,8 @@ def caseConfigSetting(st, uiCaseItem: UICaseItem): uiCaseItem.tmp_custom_config[config_input.label.value] = inputWidget(column, config=config_input, key=key) -def dbCaseConfigSetting(st, dbToCaseClusterConfigs, uiCaseItem: UICaseItem, activedDbList: list[DB]): - for db in activedDbList: +def dbCaseConfigSetting(st, dbToCaseClusterConfigs, uiCaseItem: UICaseItem, activeDbList: list[DB]): + for db in activeDbList: columns = st.columns(1 + DB_CASE_CONFIG_SETTING_COLUMNS) # column 0 - title dbColumn = columns[0] diff --git a/vectordb_bench/frontend/components/run_test/dbConfigSetting.py b/vectordb_bench/frontend/components/run_test/dbConfigSetting.py index a2d2de77f..b48bb2f35 100644 --- a/vectordb_bench/frontend/components/run_test/dbConfigSetting.py +++ b/vectordb_bench/frontend/components/run_test/dbConfigSetting.py @@ -4,12 +4,12 @@ from vectordb_bench.frontend.utils import inputIsPassword -def dbConfigSettings(st, activedDbList: list[DB]): +def dbConfigSettings(st, activeDbList: list[DB]): expander = st.expander("Configurations for the selected databases", True) dbConfigs = {} isAllValid = True - for activeDb in activedDbList: + for activeDb in activeDbList: dbConfigSettingItemContainer = expander.container() dbConfig = dbConfigSettingItem(dbConfigSettingItemContainer, activeDb) try: diff --git a/vectordb_bench/frontend/components/run_test/dbSelector.py b/vectordb_bench/frontend/components/run_test/dbSelector.py index 0864a4986..2d6f8a756 100644 --- a/vectordb_bench/frontend/components/run_test/dbSelector.py +++ b/vectordb_bench/frontend/components/run_test/dbSelector.py @@ -16,11 +16,11 @@ def dbSelector(st: st): ) dbContainerColumns = st.columns(DB_SELECTOR_COLUMNS, gap="small") - dbIsActived = {db: False for db in DB_LIST} + dbIsActivated = {db: False for db in DB_LIST} for i, db in enumerate(DB_LIST): column = dbContainerColumns[i % DB_SELECTOR_COLUMNS] - dbIsActived[db] = column.checkbox(db.name) + dbIsActivated[db] = column.checkbox(db.name) image_src = DB_TO_ICON.get(db, None) if image_src: column.markdown( @@ -29,6 +29,6 @@ def dbSelector(st: st): ) else: column.warning(f"{db.name} image not available") - activedDbList = [db for db in DB_LIST if dbIsActived[db]] + activatedDbList = [db for db in DB_LIST if dbIsActivated[db]] - return activedDbList + return activatedDbList diff --git a/vectordb_bench/frontend/components/run_test/generateTasks.py b/vectordb_bench/frontend/components/run_test/generateTasks.py index d8a678ffc..e4c6002b9 100644 --- a/vectordb_bench/frontend/components/run_test/generateTasks.py +++ b/vectordb_bench/frontend/components/run_test/generateTasks.py @@ -2,10 +2,10 @@ from vectordb_bench.models import CaseConfig, CaseConfigParamType, TaskConfig -def generate_tasks(activedDbList: list[DB], dbConfigs, activedCaseList: list[CaseConfig], allCaseConfigs): +def generate_tasks(activatedDbList: list[DB], dbConfigs, activatedCaseList: list[CaseConfig], allCaseConfigs): tasks = [] - for db in activedDbList: - for case in activedCaseList: + for db in activatedDbList: + for case in activatedCaseList: task = TaskConfig( db=db.value, db_config=dbConfigs[db], diff --git a/vectordb_bench/frontend/components/welcome/welcomePrams.py b/vectordb_bench/frontend/components/welcome/welcomePrams.py index 48bf5995c..82a813d00 100644 --- a/vectordb_bench/frontend/components/welcome/welcomePrams.py +++ b/vectordb_bench/frontend/components/welcome/welcomePrams.py @@ -62,20 +62,20 @@ def welcomePrams(st): "link": "results", }, { - "title": "Quries Per Dollar", + "title": "Queries Per Dollar", "description": ( "" - "To view the results of quries per dollar.
" + "To view the results of queries per dollar.
" "(similar to qps in Results) " "
" ), "image": "fig/homepage/qp$.png", - "link": "quries_per_dollar", + "link": "queries_per_dollar", }, { "title": "Tables", "description": ( - "" "To view the results of differnt datasets in tables." "" + "" "To view the results of different datasets in tables." "" ), "image": "fig/homepage/table.png", "link": "tables", @@ -94,7 +94,7 @@ def welcomePrams(st): "title": "Label Filter Performance", "description": ( "" - "To view the perfomance of datasets under different label filter ratios " + "To view the performance of datasets under different label filter ratios " "" ), "image": "fig/homepage/label_filter.png", @@ -104,7 +104,7 @@ def welcomePrams(st): "title": "Int Filter Performance", "description": ( "" - "To view the perfomance of datasets under different int filter ratios " + "To view the performance of datasets under different int filter ratios " "" ), "image": "fig/homepage/label_filter.png", @@ -114,7 +114,7 @@ def welcomePrams(st): "title": "Streaming Performance", "description": ( "" - "To view the perfomance of datasets under different search stages and insertion rates. " + "To view the performance of datasets under different search stages and insertion rates. " "" ), "image": "fig/homepage/streaming.png", diff --git a/vectordb_bench/frontend/config/dbCaseConfigs.py b/vectordb_bench/frontend/config/dbCaseConfigs.py index 9348c243e..5e92e9073 100644 --- a/vectordb_bench/frontend/config/dbCaseConfigs.py +++ b/vectordb_bench/frontend/config/dbCaseConfigs.py @@ -157,7 +157,7 @@ def generate_normal_cases(case_id: CaseType, custom_case: dict | None = None) -> return [CaseConfig(case_id=case_id, custom_case=custom_case)] -def get_custom_case_cluter() -> UICaseItemCluster: +def get_custom_case_cluster() -> UICaseItemCluster: return UICaseItemCluster(label="Custom Search Performance Test", uiCaseItems=get_custom_case_items()) @@ -1439,7 +1439,7 @@ class CaseConfigInput(BaseModel): ) CaseConfigParamInput_pre_reordering_num_neighbors_AlloyDB = CaseConfigInput( - label=CaseConfigParamType.preReorderingNumNeigbors, + label=CaseConfigParamType.preReorderingNumNeighbors, displayLabel="Pre reordering num neighbors", inputHelp="Specifies the number of candidate neighbors to consider during the reordering \ stages after initial search identifies a set of candidates", diff --git a/vectordb_bench/frontend/pages/int_filter.py b/vectordb_bench/frontend/pages/int_filter.py index 0408fd310..86d0ce45c 100644 --- a/vectordb_bench/frontend/pages/int_filter.py +++ b/vectordb_bench/frontend/pages/int_filter.py @@ -3,9 +3,9 @@ from vectordb_bench.frontend.components.check_results.footer import footer from vectordb_bench.frontend.components.check_results.headerIcon import drawHeaderIcon from vectordb_bench.frontend.components.check_results.nav import ( - NavToQuriesPerDollar, - NavToRunTest, NavToPages, + NavToQueriesPerDollar, + NavToRunTest, ) from vectordb_bench.frontend.components.int_filter.charts import drawCharts from vectordb_bench.frontend.components.check_results.filters import getshownData @@ -43,7 +43,7 @@ def main(): # nav navContainer = st.sidebar.container() NavToRunTest(navContainer) - NavToQuriesPerDollar(navContainer) + NavToQueriesPerDollar(navContainer) # charts drawCharts(st, shownData) diff --git a/vectordb_bench/frontend/pages/label_filter.py b/vectordb_bench/frontend/pages/label_filter.py index deab8b73a..58e3293b4 100644 --- a/vectordb_bench/frontend/pages/label_filter.py +++ b/vectordb_bench/frontend/pages/label_filter.py @@ -3,9 +3,9 @@ from vectordb_bench.frontend.components.check_results.footer import footer from vectordb_bench.frontend.components.check_results.headerIcon import drawHeaderIcon from vectordb_bench.frontend.components.check_results.nav import ( - NavToQuriesPerDollar, - NavToRunTest, NavToPages, + NavToQueriesPerDollar, + NavToRunTest, ) from vectordb_bench.frontend.components.label_filter.charts import drawCharts from vectordb_bench.frontend.components.check_results.filters import getshownData @@ -43,7 +43,7 @@ def main(): # nav navContainer = st.sidebar.container() NavToRunTest(navContainer) - NavToQuriesPerDollar(navContainer) + NavToQueriesPerDollar(navContainer) # charts drawCharts(st, shownData) diff --git a/vectordb_bench/frontend/pages/qps_recall.py b/vectordb_bench/frontend/pages/qps_recall.py index 27f9c4691..16585f9f9 100644 --- a/vectordb_bench/frontend/pages/qps_recall.py +++ b/vectordb_bench/frontend/pages/qps_recall.py @@ -4,9 +4,9 @@ from vectordb_bench.frontend.components.check_results.footer import footer from vectordb_bench.frontend.components.check_results.headerIcon import drawHeaderIcon from vectordb_bench.frontend.components.check_results.nav import ( - NavToQuriesPerDollar, - NavToRunTest, NavToPages, + NavToQueriesPerDollar, + NavToRunTest, ) from vectordb_bench.frontend.components.qps_recall.charts import drawCharts from vectordb_bench.frontend.components.qps_recall.data import getshownData @@ -56,7 +56,7 @@ def case_results_filter(case_result: CaseResult) -> bool: # nav navContainer = st.sidebar.container() NavToRunTest(navContainer) - NavToQuriesPerDollar(navContainer) + NavToQueriesPerDollar(navContainer) # save or share resultesContainer = st.sidebar.container() diff --git a/vectordb_bench/frontend/pages/quries_per_dollar.py b/vectordb_bench/frontend/pages/queries_per_dollar.py similarity index 95% rename from vectordb_bench/frontend/pages/quries_per_dollar.py rename to vectordb_bench/frontend/pages/queries_per_dollar.py index 078d8490d..cfbee5db3 100644 --- a/vectordb_bench/frontend/pages/quries_per_dollar.py +++ b/vectordb_bench/frontend/pages/queries_per_dollar.py @@ -18,7 +18,7 @@ from vectordb_bench.frontend.components.get_results.saveAsImage import getResults from vectordb_bench.interface import benchmark_runner -from vectordb_bench.metric import QURIES_PER_DOLLAR_METRIC +from vectordb_bench.metric import QUERIES_PER_DOLLAR_METRIC def main(): @@ -59,7 +59,7 @@ def main(): for caseName in showCaseNames: data = [data for data in shownData if data["case_name"] == caseName] dataWithMetric = [] - metric = QURIES_PER_DOLLAR_METRIC + metric = QUERIES_PER_DOLLAR_METRIC for d in data: qps = d.get("qps", 0) price = priceMap.get(d["db"], {}).get(d["db_label"], 0) diff --git a/vectordb_bench/frontend/pages/results.py b/vectordb_bench/frontend/pages/results.py index a146f2fdc..48eaa0d05 100644 --- a/vectordb_bench/frontend/pages/results.py +++ b/vectordb_bench/frontend/pages/results.py @@ -5,9 +5,9 @@ ) from vectordb_bench.frontend.components.check_results.headerIcon import drawHeaderIcon from vectordb_bench.frontend.components.check_results.nav import ( - NavToQuriesPerDollar, - NavToRunTest, NavToPages, + NavToQueriesPerDollar, + NavToRunTest, ) from vectordb_bench.frontend.components.check_results.charts import drawCharts from vectordb_bench.frontend.components.check_results.filters import getshownData @@ -45,7 +45,7 @@ def main(): # nav navContainer = st.sidebar.container() NavToRunTest(navContainer) - NavToQuriesPerDollar(navContainer) + NavToQueriesPerDollar(navContainer) # save or share resultesContainer = st.sidebar.container() diff --git a/vectordb_bench/frontend/pages/run_test.py b/vectordb_bench/frontend/pages/run_test.py index e4472e767..c1c4fdaae 100644 --- a/vectordb_bench/frontend/pages/run_test.py +++ b/vectordb_bench/frontend/pages/run_test.py @@ -34,21 +34,21 @@ def main(): # select db dbSelectorContainer = st.container() - activedDbList = dbSelector(dbSelectorContainer) + activeDbList = dbSelector(dbSelectorContainer) # db config setting dbConfigs = {} isAllValid = True - if len(activedDbList) > 0: + if len(activeDbList) > 0: dbConfigContainer = st.container() - dbConfigs, isAllValid = dbConfigSettings(dbConfigContainer, activedDbList) + dbConfigs, isAllValid = dbConfigSettings(dbConfigContainer, activeDbList) # select case and set db_case_config caseSelectorContainer = st.container() - activedCaseList, allCaseConfigs = caseSelector(caseSelectorContainer, activedDbList) + activeCaseList, allCaseConfigs = caseSelector(caseSelectorContainer, activeDbList) # generate tasks - tasks = generate_tasks(activedDbList, dbConfigs, activedCaseList, allCaseConfigs) if isAllValid else [] + tasks = generate_tasks(activeDbList, dbConfigs, activeCaseList, allCaseConfigs) if isAllValid else [] # submit submitContainer = st.container() diff --git a/vectordb_bench/interface.py b/vectordb_bench/interface.py index 42dc876b0..8c60b5b54 100644 --- a/vectordb_bench/interface.py +++ b/vectordb_bench/interface.py @@ -108,7 +108,7 @@ def get_results(result_dir: pathlib.Path | None = None) -> list[TestResult]: def _try_get_signal(self): while self.receive_conn and self.receive_conn.poll(): sig, received = self.receive_conn.recv() - log.debug(f"Sigal received to process: {sig}, {received}") + log.debug(f"Signal received to process: {sig}, {received}") if sig == SIGNAL.ERROR: self.latest_error = received self._clear_running_task() @@ -123,13 +123,13 @@ def _try_get_signal(self): self._clear_running_task() def has_running(self) -> bool: - """check if there're running benchmarks""" + """check if there are running benchmarks""" if self.running_task: self._try_get_signal() return self.running_task is not None def stop_running(self): - """force stop if ther're running benchmarks""" + """force stop if there are running benchmarks""" self._clear_running_task() def get_tasks_count(self) -> int: diff --git a/vectordb_bench/log_util.py b/vectordb_bench/log_util.py index 69dae293d..6b09f6751 100644 --- a/vectordb_bench/log_util.py +++ b/vectordb_bench/log_util.py @@ -65,22 +65,21 @@ class colors: ENDC = "\033[0m" -COLORS = { +_BASE_LEVEL_COLORS = { "INFO": colors.INFO, - "INFOM": colors.INFO, "DEBUG": colors.DEBUG, - "DEBUGM": colors.DEBUG, "WARNING": colors.WARNING, - "WARNINGM": colors.WARNING, - "CRITICAL": colors.CRITICAL, - "CRITICALM": colors.CRITICAL, "ERROR": colors.ERROR, - "ERRORM": colors.ERROR, + "CRITICAL": colors.CRITICAL, +} +COLORS = { + **_BASE_LEVEL_COLORS, + **{f"{level}M": color for level, color in _BASE_LEVEL_COLORS.items()}, "ENDC": colors.ENDC, } -class ColorFulFormatColMixin: +class ColorfulFormatColMixin: def format_col(self, message: str, level_name: str): if level_name in COLORS: message = COLORS[level_name] + message + COLORS["ENDC"] @@ -103,7 +102,7 @@ def __getattr__(self, attr: any): return getattr(self, attr) -class ColorfulFormatter(ColorFulFormatColMixin, logging.Formatter): +class ColorfulFormatter(ColorfulFormatColMixin, logging.Formatter): def format(self, record: any): proxy = ColorfulLogRecordProxy(record) return super().format(proxy) diff --git a/vectordb_bench/metric.py b/vectordb_bench/metric.py index 3634b2114..92a8d54c5 100644 --- a/vectordb_bench/metric.py +++ b/vectordb_bench/metric.py @@ -13,7 +13,7 @@ class Metric: # for load cases max_load_count: int = 0 - # for both performace and streaming cases + # for both performance and streaming cases insert_duration: float = 0.0 optimize_duration: float = 0.0 load_duration: float = 0.0 # insert + optimize @@ -49,7 +49,7 @@ class Metric: st_conc_latency_avg_list_list: list[list[float]] = field(default_factory=list) -QURIES_PER_DOLLAR_METRIC = "QP$ (Quries per Dollar)" +QUERIES_PER_DOLLAR_METRIC = "QP$ (Queries per Dollar)" LOAD_DURATION_METRIC = "load_duration" SERIAL_LATENCY_P99_METRIC = "serial_latency_p99" SERIAL_LATENCY_P95_METRIC = "serial_latency_p95" @@ -62,7 +62,7 @@ class Metric: SERIAL_LATENCY_P99_METRIC: "ms", SERIAL_LATENCY_P95_METRIC: "ms", MAX_LOAD_COUNT_METRIC: "K", - QURIES_PER_DOLLAR_METRIC: "K", + QUERIES_PER_DOLLAR_METRIC: "K", } lower_is_better_metrics = [ diff --git a/vectordb_bench/models.py b/vectordb_bench/models.py index cce0fa116..c022bcb83 100644 --- a/vectordb_bench/models.py +++ b/vectordb_bench/models.py @@ -104,7 +104,7 @@ class CaseConfigParamType(Enum): maxNumLevels = "max_num_levels" numLeavesToSearch = "num_leaves_to_search" maxTopNeighborsBufferSize = "max_top_neighbors_buffer_size" - preReorderingNumNeigbors = "pre_reordering_num_neighbors" + preReorderingNumNeighbors = "pre_reordering_num_neighbors" numSearchThreads = "num_search_threads" maxNumPrefetchDatasets = "max_num_prefetch_datasets" storage_engine = "storage_engine" From d66414d9b0cd1a2aa7253c2d112c0aae37c75efb Mon Sep 17 00:00:00 2001 From: niebayes Date: Mon, 22 Dec 2025 08:22:45 +0000 Subject: [PATCH 2/2] fix --- .github/workflows/pull_request.yml | 1 - typos.toml | 4 +++- vectordb_bench/backend/clients/pgvecto_rs/config.py | 6 +++--- vectordb_bench/log_util.py | 13 +++++++------ 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 05e0ac46a..9fa68c523 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -31,7 +31,6 @@ jobs: run: | python -m pip install --upgrade pip pip install -e ".[test]" - pip install codespell - name: Run typo checks uses: crate-ci/typos@v1.40.0 diff --git a/typos.toml b/typos.toml index 578d2b41d..c4067b2c7 100644 --- a/typos.toml +++ b/typos.toml @@ -1,3 +1,5 @@ +# Respect these words as correct spelling. [default.extend-words] -# Respect RaBit, RaBitQ as correct spelling. "rabit" = "rabit" +"typ" = "typ" +"infom" = "infom" diff --git a/vectordb_bench/backend/clients/pgvecto_rs/config.py b/vectordb_bench/backend/clients/pgvecto_rs/config.py index 37570b0b6..fbb7c5d81 100644 --- a/vectordb_bench/backend/clients/pgvecto_rs/config.py +++ b/vectordb_bench/backend/clients/pgvecto_rs/config.py @@ -85,7 +85,7 @@ def index_param(self) -> dict[str, str]: if self.quantization_type is None: quantization = None else: - quantization = Quantization(type=self.quantization_type, ratio=self.quantization_ratio) + quantization = Quantization(typ=self.quantization_type, ratio=self.quantization_ratio) option = IndexOption( index=Hnsw( @@ -113,7 +113,7 @@ def index_param(self) -> dict[str, str]: if self.quantization_type is None: quantization = None else: - quantization = Quantization(type=self.quantization_type, ratio=self.quantization_ratio) + quantization = Quantization(typ=self.quantization_type, ratio=self.quantization_ratio) option = IndexOption( index=Ivf(nlist=self.lists, quantization=quantization), @@ -135,7 +135,7 @@ def index_param(self) -> dict[str, str]: if self.quantization_type is None: quantization = None else: - quantization = Quantization(type=self.quantization_type, ratio=self.quantization_ratio) + quantization = Quantization(typ=self.quantization_type, ratio=self.quantization_ratio) option = IndexOption( index=Flat( diff --git a/vectordb_bench/log_util.py b/vectordb_bench/log_util.py index 6b09f6751..d7cea9afe 100644 --- a/vectordb_bench/log_util.py +++ b/vectordb_bench/log_util.py @@ -65,16 +65,17 @@ class colors: ENDC = "\033[0m" -_BASE_LEVEL_COLORS = { +COLORS = { "INFO": colors.INFO, + "INFOM": colors.INFO, "DEBUG": colors.DEBUG, + "DEBUGM": colors.DEBUG, "WARNING": colors.WARNING, - "ERROR": colors.ERROR, + "WARNINGM": colors.WARNING, "CRITICAL": colors.CRITICAL, -} -COLORS = { - **_BASE_LEVEL_COLORS, - **{f"{level}M": color for level, color in _BASE_LEVEL_COLORS.items()}, + "CRITICALM": colors.CRITICAL, + "ERROR": colors.ERROR, + "ERRORM": colors.ERROR, "ENDC": colors.ENDC, }