Skip to main content

High-performance dictionary engine based on FST

Project description

fstd

A dictionary engine powered by Finite State Transducers, a data structure that enables us to search in dictionaries with many ways, including regex, suggesting based on edit distance, other than just prefix search powered by trie data structure used by traditional dictionaries. Fstd dictionary provides two format file: fstdx and fstdd , which is similar to the popular dictionary format: mdx and mdd. A fstdtools that can convert mdx/mdd to fstdx/fstdd.

Features

  • Multiple threads are supported to offer high-performance search and dictionary compilation.
  • Regex search.
  • Fuzzy search: suggest candidates sorted by the similarity calculated by edit distance to input keyword.
  • Prefix distance search: provide candidates sorted by the distance calculated by common prefix and prior suffix. By providing prior suffix, it can top the candidates that has a longer common prefix with input keyword and has a prior suffix. It's useful to help us find the simple form of an verb in a language whose verb has some constant suffix, such as Japanese ("する", "う", "く", "ぐ", "す", "つ", "ぬ", "ぶ", "む", "る", "い") or Korean ("하다", "다"). However, it's not always effective in all cases.
  • Prefix search(predictive), a way as the same as traditional dictionaries can provide.
  • Esay to convert from mdx/mdd to fstdx/fstdd.
  • Data related to dictionaries is compressed to reduce disk usage.
  • Low memory usage and high-performance search, as the FST made by compiling entry words of a dictionary is loaded into memory to support high-performance search. FST is a data structure providing a better compression rate than trie, because it can not only compress common prefix but also common suffix.
  • Python support by import fstd

Install

It has been tested on Macos and Linux platform now. On Windows platform, there might be a bug while launching a thread pool. It's not convenient to fix it because I don't have a windows machine. Pull a request to me if you can fix it.

Python

pip install fstd

It's recommanded to install a python command line tool fstdtools as it offers a safer and more friendly usage than the CLI compiled from c plus plus.

pip install fstdtools
fstdtools --version

Install from source code

  1. Install dependence
brew install cmake googletest indicators spdlog fmt zstd pcre2 nlohmann-json cli11
  1. Compile and install
git clone https://github.com/MouJieQin/fstd.git
cd fstd
mkdir build && cd build
cmake ..
make install -j8
fstd -h
  1. Run test
make check

Usage

Python

To run the demo.py, you should have a directory named dictionaries with a structure like this, fstdx files are required.

dictionaries
├── dict1
│   ├── dict1.css
│   ├── dict1.fstdd
│   ├── dict1.fstdx
│   ├── dict1.js
│   └── dict1.png
├── dict2
│   ├── dict2.css
│   ├── dict2.fstdd
│   ├── dict2.fstdx
│   ├── dict2.js
│   └── dict2.png
└── dict3
    ├── dict1.css
    ├── dict1.fstdd
    ├── dict1.fstdx
    ├── dict1.js
    └── dict1.png
# demo.py
import os
import sys
from pathlib import Path
import fstd


class FstdSearcher:
    def __init__(self, dicts_path: str):
        fstd.set_log_level(4)
        self._all_dict_names: list[str] = []
        self._fstd_searcher: fstd.FstdxSearcher = fstd.FstdxSearcher()
        self._prior_suf = ["する", "う", "く", "ぐ", "す", "つ", "ぬ", "ぶ", "む", "る", "い", "하다", "다"]
        self._fstd_searcher.insert_prior_suffix(self._prior_suf)
        self._load_dicts(dicts_path)

    def _load_dicts(self, dicts_path: str) -> None:
        """
        Load the dictionaries from the path.
        :param dicts_path: the path to the dictionaries
        """
        for dict_path in os.listdir(dicts_path):
            if os.path.isdir(os.path.join(dicts_path, dict_path)):
                for file in os.listdir(os.path.join(dicts_path, dict_path)):
                    if file.endswith(".fstdx"):
                        dict_name = Path(dict_path).name
                        self._all_dict_names.append(dict_name)
                        self._fstd_searcher.insert_if_not_exists(dict_name, os.path.join(dicts_path, dict_path, file))
                        print(f"Load dictionary {dict_name} from {os.path.join(dicts_path, dict_path, file)}")

    def lookup(
        self,
        keyword: str,
        dict_names: list[str],
    ) -> dict[str, list[str]]:
        """
        Lookup the keyword in the dictionaries.
        :param keyword: the keyword to lookup
        :param dict_names: the dictionaries to lookup
        :return: the results of the lookup,a dictionary of dict_name -> result
        """
        results = {}
        dict_names = dict_names or self._all_dict_names
        for dict_name in dict_names:
            res = self._fstd_searcher.exact_match_search(keyword, dict_name)
            if res:
                result = []
                self._hand_link_word(result, res, dict_name, [keyword])
                results[dict_name] = result
        return results

    def _hand_link_word(
        self,
        result: list[str],
        cur_result: list[str],
        dict_name: str,
        words_show: list[str],
    ):
        """
        Process the redirect words in the result.
        :param result: the result to append the words
        :param cur_result: the current result to process
        :param dict_name: the dictionary name to process
        :param words_show: the words to show
        """
        for i in range(len(cur_result)):
            item = cur_result[i]
            if "@@@LINK=" not in item:
                result.append(item)
            else:
                redirect_word = item.split("@@@LINK=")[1].strip()
                if redirect_word not in words_show:
                    words_show.append(redirect_word)
                    res_redirect = self._fstd_searcher.exact_match_search(redirect_word, dict_name)
                    if res_redirect:
                        self._hand_link_word(
                            result, res_redirect, dict_name, words_show
                        )

    def keyword_options_search(
        self,
        keyword: str,
        search_method: str,
        dict_names: list[str]
    ):
        """
        Search the keyword in the dictionaries using the search method.
        :param keyword: the keyword to search
        :param search_method: the search method to use
        :param dict_names: the dictionaries to search
        :return: the results of the search,a dictionary of dict_name -> result
        """
        use_dicts = dict_names or self._all_dict_names
        if search_method == "prefix_search":
            return self._fstd_searcher.predictive_search(keyword, use_dicts)

        elif search_method == "suggest":
            return self._fstd_searcher.suggest(keyword, use_dicts)

        elif search_method == "regex_search":
            return self._fstd_searcher.regex_search(keyword, use_dicts)

        elif search_method == "prefix_distance_search":
            return self._fstd_searcher.prefix_distance_search(keyword, use_dicts, 3)

        else:
            print(f"Invalid search method: {search_method}", file=sys.stderr)
            return []


def print_options_result(method: str, results: list[str]) -> None:
    """
    Print the results of the options search.
    :param results: the results of the options search
    """
    print(f"\nResults of {method}: ----------")
    for result in results:
        print(result)


def main():
    fstd_searcher = FstdSearcher("./dictionaries")
    print("start search....")
    results = fstd_searcher.keyword_options_search("suggst", "suggest", ["dict1","dict2"])
    print_options_result("suggest", results)
    results = fstd_searcher.keyword_options_search("振り返ってるのは", "prefix_distance_search", [])
    print_options_result("prefix_distance_search", results)
    results = fstd_searcher.keyword_options_search("dict.*n.*y$", "regex_search", [])
    if results[1]:
        print(f"Regex error: {results[1]}")
    else:
        print_options_result("regex_search", results[0])

    results = fstd_searcher.lookup("do", [])
    print("\nlookup:-------")
    for dict_name, result in results.items():
        print(f"{dict_name}: --------")
        for item in result:
            print("---------")
            print(item)


if __name__ == "__main__":
    main()

API Reference

class FstdxSearcher:
    """
    Multi-dictionary search manager, load multiple fstdx and batch search
    """

    @overload
    def __init__(self, worker_num: int = 0) -> None:
        """
        Initialize the searcher with worker_num.
        :param worker_num: the number of threads to use for search
        :default worker_num is 0, automatically use all the current threads
        """
        ...

    @overload
    def __init__(self, meta_json_path: str, worker_num: int = 0) -> None:
        """
        Initialize the searcher with meta_json_path and worker_num.
        :param meta_json_path: the path to the meta json file
        :param worker_num: the number of threads to use for search
        :default worker_num is 0, automatically use all the current threads
        """
        ...

    def compile_fstdx(*args, **kwargs) -> None:
        ...

    def __bool__(self) -> bool:
        """Check if the searcher is valid."""
        ...

    def is_valid(self) -> bool:
        """
        Check if the searcher is valid.
        :return: True if the searcher is valid, False otherwise
        """
        ...

    def extract(self, name: str, file_path: str, dst_dir: str = "") -> bool:
        """
        Extract file_path from the fstdd files found in the same directory as the fstdx file.
        :param name: the name of the dictionary
        :param file_path: the path(key) to the file to extract
        :param dst_dir: the destination directory to extract the files, if empty, will extract to the default directory
        :return: True if the extraction is successful, False otherwise
        """
        ...

    def contains(self, word: str, names: Sequence[str]) -> bool:
        """
        Check if the word is in the dictionaries.
        :param word: the word to check
        :param names: the names of dictionaries to check
        :return: True if the word is in the dictionaries, False otherwise
        """
        ...

    @overload
    def exact_match_search(self, word: str, name: str) -> List[str]:
        """
        Search the word in the dictionary with name.
        :param word: the word to search
        :param name: the name of the dictionary to search
        :return: the results of the search
        """
        ...

    @overload
    def exact_match_search(self, word: str, names: Sequence[str]) -> dict[str, list[str]]:
        """
        Search the word in the dictionaries with names.
        :param word: the word to search
        :param names: the names of dictionaries to search
        :return: the results of the search
        """
        ...

    def exact_match_search(*args, **kwargs) -> List[str]:
        ...

    def common_prefix_search(self, word: str, names: Sequence[str]) -> List[str]:
        """
        Search the longest common prefix of the word in the dictionaries.
        :param word: the word to search
        :param names: the names of dictionaries to search
        :return: the length of the longest common prefix in the dictionaries.
        """
        ...

    def longest_prefix_len(self, word: str, names: Sequence[str]) -> int:
        """
        Search the longest common prefix of the word in the dictionaries.
        :param word: the word to search
        :param names: the names of dictionaries to search
        :return: the results of the search
        """
        ...

    def edit_distance_search(self, word: str, names: Sequence[str], edit_distance: int = 1) -> List[str]:
        """
        Search the word in the dictionaries with edit distance.
        :param word: the word to search
        :param names: the names of dictionaries to search
        :param edit_distance: the maximum edit distance
        :return: the results of the search
        """
        ...

    def predictive_search(self, word: str, names: Sequence[str]) -> List[str]:
        """
        Perform predictive search for the word in the dictionaries.
        :param word: the word to search
        :param names: the names of dictionaries to search
        :return: the results of the search
        """
        ...

    def suggest(self, word: str, names: Sequence[str]) -> List[str]:
        """
        Provide suggestions for the word in the dictionaries.
        :param word: the word to search
        :param names: the names of dictionaries to search
        :return: the suggested words
        """
        ...

    def prefix_distance_search(self, word: str, names: Sequence[str], max_distance: int = 1) -> List[str]:
        """
        Search the word in the dictionaries with prefix distance.
        :param word: the word to search
        :param names: the names of dictionaries to search
        :param max_distance: the maximum prefix distance
        :return: the results of the search
        """
        ...

    def regex_search(self, pattern: str, names: Sequence[str]) -> Tuple[List[str], str]:
        """
        Search the word in the dictionaries with regex.
        :param pattern: the regex pattern to search
        :param names: the names of dictionaries to search
        :return: the words that match the regex pattern in the dictionary in tuple[0], the error message if any in tuple[1]
        """
        ...

    def insert_prior_suffix(self, sufs: Sequence[str]) -> None:
        """
        Insert prior suffixes for the dictionaries.
        :param sufs: the prior suffixes to insert
        """
        ...

    def insert_if_not_exists(self, name: str, fstdx_path: str) -> None:
        """
        Insert the fstdx file if it does not exist.
        :param name: the name of the dictionary
        :param fstdx_path: the path to the fstdx file
        :return: True if the insertion is successful, False otherwise
        """
        ...

    def insert(self, name: str, fstdx_path: str) -> bool:
        """
        Insert the fstdx file.
        :param name: the name of the dictionary
        :param fstdx_path: the path to the fstdx file
        :return: True if the insertion is successful, False otherwise
        """
        ...

    def save_to_disk(self, meta_json_path: str) -> bool:
        """
        Save the meta json to disk.
        :param meta_json_path: the path to save the meta json
        :return: True if the save is successful, False otherwise
        """
        ...

C plus plus

  1. Compile fstdx/fstdd
# go to the project directory
cd fstd
# use default configure to compile a fstdx
fstd write -f tests/dict/dict.txt -o dict.fstdx
# use default configure to compile a fstdd. Note: fstdd normally include resource data, such as pictures and audios, but we use the project lib directory for test.
fstd write -f lib -o dict.fstdd

The raw content of tests/dict/dict.txt :

  1. The first entry requires no preceding delimiter: write the entry word (key) directly, followed by its corresponding definition (value). Definitions can span multiple lines, but entry words must stay on a single line.
  2. Starting from the second entry, each entry word (key) must be preceded by the delimiter </>. Entry words must still be written on one line, while definitions can span multiple lines.
  3. The end of each complete entry (entry word + corresponding definition) must be marked with the delimiter </> as a closing tag.
Ab
The definition of Ab
</>
Ababdeh
The definition of Ababdeh
</>
Abby
The definition of Abby
</>
...
  1. Search in a fstdx
# show meta data
> fstd search -m dict.fstdx
{
   "Compressionlevel": 5,
   "Creationdate": "2026-06-28",
   "Description": "",
   "Encoding": "UTF-8",
   "Format": "Html",
   "Keycasesensitive": false,
   "Left2Right": true,
   "Record": 23603,
   "Stripkey": true,
   "Stylesheet": "",
   "Title": "",
   "Version": "0.1.0"
}

# exact match search
> fstd search 'Ababdeh'  dict.fstdx
------------------------------
The definition of Ababdeh
------------------------------

# regex search
> fstd search -r 'di.*na.*y' dict.fstdx
dictionary
disciplinability
disproportionality
disproportionably

# suggest search
> fstd search -g 'dicioa' dict.fstdx
dictionary -> 0.544
dilo -> 0.438889
diol -> 0.438889
radicicola -> 0.42
decoat -> 0.4
disc -> 0.303704
io -> 0.185185
coca -> 0.175926

# fuzzy search
> fstd search -e 5 'dicionary' dict.fstdx
congiary
dictionary
donary
missionary
ordinary

# enumerate all entry words in a dictionary
> fstd search -u dict.fstdx
Ab
Aberia
Abelite
Abietineae
Ababdeh
Abby
Acanthodidae
Acarus
...
  1. Search in multiple fstdx

It's just an example of showing how to search in multiple fstdx dictionaries. The project does not provide the following fstdx files.

# Prefix distance search in multiple fstdx dicionaries
>  fstd search -P 2 振り返ってみます -f lj.fstdx -f dcq.fstdx -f hgy.fstdx
振り返る
振り
振り乱す
振り仰ぐ
振り出す
振り切る
振り合う
...

> fstd search -P 2 알아보겠습 -f lj.fstdx -f dcq.fstdx -f hgy.fstdx
알아보다
알아보
알아보-
알아내다
알아듣다
알아먹다
알아주다
알아채다
알다
...
  1. Extract a file from a fstdd
# list all keys of a fstdd
> fstd search -u dict.fstdd
include/fstd/common.h
include/fstd/fstdd_compressor.h
include/fstd/fstdd_reader.h
include/fstd/fstdd_writer.h
...

# extract include/fstd/common.h from the fstdd to the data directory
> fstd extract -k include/fstd/common.h -o data dict.fstdd

API reference

namespace fstd {

class FstdxSearcher {

public:
   FstdxSearcher(size_t worker_num = 0);

   FstdxSearcher(const std::string &meta_json_path, size_t worker_num = 0);

   operator bool() const;

   bool extract(const std::string &name, const std::string &file_path,
               const std::string &dst_dir) const;

   bool extract(const std::string &name, const std::string &file_path) const;

   bool contains(std::string_view word,
                  const std::vector<std::string> &names) const;

   std::vector<std::string> search(std::string_view word,
                                    const std::string &name) const;

   std::unordered_map<std::string, std::vector<std::string>>
   search(std::string_view word, const std::vector<std::string> &names) const;

   std::vector<std::string>
   common_prefix_search(std::string_view word,
                        const std::vector<std::string> &names) const;

   size_t
   longest_prefix_len(std::string_view word,
                                 const std::vector<std::string> &names) const;

   std::vector<std::string>
   edit_distance_search(std::string_view word,
                        const std::vector<std::string> &names,
                        size_t edit_distance = 1) const;

   std::vector<std::string>
   predictive_search(std::string_view word,
                     const std::vector<std::string> &names) const;

   std::vector<std::string> suggest(std::string_view word,
                                    const std::vector<std::string> &names) const;

   std::vector<std::string>
   prefix_distance_search(std::string_view word,
                           const std::vector<std::string> &names,
                           size_t max_distance) const;

   std::pair<std::vector<std::string>, std::string>
   regex_search(std::string_view pattern,
               const std::vector<std::string> &names) const;

   void insert_prior_suffix(const std::vector<std::string> &sufs);

   void insert_if_not_exists(const std::string &name,
                              const std::string &fstdx_path);

   bool insert(const std::string &name, const std::string &fstdx_path);

   bool save_to_disk(const std::string &meta_json_path);
}
}

Reference

Based on cpp-fstlib by yhirose.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

fstd-0.1.8-cp312-cp312-win_amd64.whl (2.3 MB view details)

Uploaded CPython 3.12Windows x86-64

fstd-0.1.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

fstd-0.1.8-cp312-cp312-macosx_11_0_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.12macOS 11.0+ x86-64

fstd-0.1.8-cp312-cp312-macosx_11_0_arm64.whl (3.3 MB view details)

Uploaded CPython 3.12macOS 11.0+ ARM64

fstd-0.1.8-cp311-cp311-win_amd64.whl (2.3 MB view details)

Uploaded CPython 3.11Windows x86-64

fstd-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

fstd-0.1.8-cp311-cp311-macosx_11_0_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.11macOS 11.0+ x86-64

fstd-0.1.8-cp311-cp311-macosx_11_0_arm64.whl (3.3 MB view details)

Uploaded CPython 3.11macOS 11.0+ ARM64

fstd-0.1.8-cp310-cp310-win_amd64.whl (2.3 MB view details)

Uploaded CPython 3.10Windows x86-64

fstd-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

fstd-0.1.8-cp310-cp310-macosx_11_0_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.10macOS 11.0+ x86-64

fstd-0.1.8-cp310-cp310-macosx_11_0_arm64.whl (3.3 MB view details)

Uploaded CPython 3.10macOS 11.0+ ARM64

fstd-0.1.8-cp39-cp39-win_amd64.whl (2.3 MB view details)

Uploaded CPython 3.9Windows x86-64

fstd-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (3.8 MB view details)

Uploaded CPython 3.9manylinux: glibc 2.17+ x86-64

fstd-0.1.8-cp39-cp39-macosx_11_0_x86_64.whl (3.7 MB view details)

Uploaded CPython 3.9macOS 11.0+ x86-64

fstd-0.1.8-cp39-cp39-macosx_11_0_arm64.whl (3.3 MB view details)

Uploaded CPython 3.9macOS 11.0+ ARM64

File details

Details for the file fstd-0.1.8-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: fstd-0.1.8-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fstd-0.1.8-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 0363c2b1dba4576056694adcc415834d10bcb9a27365f15e27c9d32c4e98bee9
MD5 41ce35e1ee371d839045c3111a8136dd
BLAKE2b-256 47545f3dcedac0ddc0194707e6df8e9465cb8748455dccf0f49c87cf83cc44f5

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp312-cp312-win_amd64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 a5464f103283704e3193058257e1ff23bec89f08203cfa19e8c6b99d8dac2ad4
MD5 d07e90bb04dc98b79b7ec1502a7ac228
BLAKE2b-256 a1d76c5f1a4ff354865c2a3ffb5cfc1d85b9fd6eb4dbea6df53dd792f3567a44

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp312-cp312-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp312-cp312-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 e5fe8b64f0538b5a0711ad1d45fa702662f8b243995b8c5deaaf3a0e867fe27b
MD5 74162b3810ef2ab03ce43b65abd18c59
BLAKE2b-256 350e03563127d01c7cb92c1a281622331ddf347117fcc411e76903d1fcd1db0f

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp312-cp312-macosx_11_0_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp312-cp312-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp312-cp312-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 aac6667ac2c69250fd88de87e9883642fd264db4cd3199c21193a6b44e3d3eb6
MD5 794e85237cec67146b9513881251ddfd
BLAKE2b-256 a4b8512d3d3672af337350c093c093b6f4b4398c2686b6b117936cc3c03651f1

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp312-cp312-macosx_11_0_arm64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp311-cp311-win_amd64.whl.

File metadata

  • Download URL: fstd-0.1.8-cp311-cp311-win_amd64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: CPython 3.11, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fstd-0.1.8-cp311-cp311-win_amd64.whl
Algorithm Hash digest
SHA256 5e40d456ba80fed58ec39f98863dc65707ec9f572c283174cb59a4b9a906c139
MD5 fee0e06daaf4af33555158a502fc7daa
BLAKE2b-256 2316905399d95c9a7686e3db138c09eb169a5a5862870ff2355fd1526852a6cd

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp311-cp311-win_amd64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 8621a960fab80436c206cd4f20ede740c118f402ac33525decec1245ebb26c11
MD5 a0c8202481502b44373ce8835c030b26
BLAKE2b-256 7885acdc83219ef76744792336c24d02e685e37bbc6c87c9f5fe480f11a06992

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp311-cp311-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp311-cp311-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 19c5b0fbb7d74e783ccf0582660e7348abd721f10f5dbb385a4063b688ed249e
MD5 d7a2ec0b7bdb37a9704f492bfcf6700f
BLAKE2b-256 82c60779cb5ece6452aeaafa22c6632e4ae0039d0d80de560be782672138c8e8

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp311-cp311-macosx_11_0_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp311-cp311-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp311-cp311-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 64df880d9f096453985fb2f0150a2616ec6d5d2ede9d9083daf52212b20a98e8
MD5 fce0319406270d69758f4718c1c57fcc
BLAKE2b-256 cd7f36f36a90f98823e7ae07dcbe032327665002fabb0bb568a69d59d32bf8d2

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp311-cp311-macosx_11_0_arm64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp310-cp310-win_amd64.whl.

File metadata

  • Download URL: fstd-0.1.8-cp310-cp310-win_amd64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: CPython 3.10, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fstd-0.1.8-cp310-cp310-win_amd64.whl
Algorithm Hash digest
SHA256 1a66447f5e2dd8b6e735ee107ea69f29234fc489f4ce7008cb8230da002e2a60
MD5 4f276f0c53bcb5b2d9b3aff1ca5a2a52
BLAKE2b-256 2cced93f38de7fc0d08acae5fc393dcbc626b763c26375fafd94a6e733d4ca37

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp310-cp310-win_amd64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 eec3fdc90d9df24958de498fac43b62ad877987ed51a1ea8c29297f1405da769
MD5 2b0a1c258ea22c8d8bfbebb89532b430
BLAKE2b-256 c6621623555d0947bcab1ff55f0912e1838ee6c1946d49a98e940aa7d6b381e9

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp310-cp310-macosx_11_0_x86_64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp310-cp310-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 34748030cd0b82554bf4cf71df94fb5509d8bca8c1f491c6d81003210258f5b4
MD5 c9fcc61d8b3c092df1623d6ac5dbf8f6
BLAKE2b-256 0211b64312dedde161f53f332641798496e295bb4ce22e4e409b8b75741093c5

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp310-cp310-macosx_11_0_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp310-cp310-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp310-cp310-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 dc4a1837a2d20a900083eaf078fee40555acf482d84e48d9c7beaf7441fc841b
MD5 47a395b2e985397aed9f7046b01b922c
BLAKE2b-256 6eb1677bfc685446357bdd30951b27486cb23805c11d8e8d87db0a5244b04300

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp310-cp310-macosx_11_0_arm64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp39-cp39-win_amd64.whl.

File metadata

  • Download URL: fstd-0.1.8-cp39-cp39-win_amd64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: CPython 3.9, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fstd-0.1.8-cp39-cp39-win_amd64.whl
Algorithm Hash digest
SHA256 a37de547f6aacb1183988c8aae97ba472d5f308301609f17cb17dc2d101960ba
MD5 4e1cc9fb242e9fddc4802e4cb6603137
BLAKE2b-256 12984f94d21b3f6ccf3ab7085ca9701037d620578399dc61b210d745343cdcc4

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp39-cp39-win_amd64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for fstd-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fb55777813cb626b2a5aeecef46e9076c615d9e90e1ccf823ac0e6e02db2909f
MD5 00cc5a6f5a4dce70386cbce9bd709ae9
BLAKE2b-256 d706b99fde5ee01f392ca029dce0f578b7ceccb6dc13b4ef8e871b96fa938ece

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp39-cp39-macosx_11_0_x86_64.whl.

File metadata

  • Download URL: fstd-0.1.8-cp39-cp39-macosx_11_0_x86_64.whl
  • Upload date:
  • Size: 3.7 MB
  • Tags: CPython 3.9, macOS 11.0+ x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fstd-0.1.8-cp39-cp39-macosx_11_0_x86_64.whl
Algorithm Hash digest
SHA256 7092482d54ae4e53cc7da93edd7093f124a19e627dc95fc1cc91e7d15edf287b
MD5 b315e754e1f6ab57696ec46e079a1aa5
BLAKE2b-256 def778527a56d8d36badd05831c332e4c357d29d9e48a0ffe33d78f93f17aa31

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp39-cp39-macosx_11_0_x86_64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fstd-0.1.8-cp39-cp39-macosx_11_0_arm64.whl.

File metadata

  • Download URL: fstd-0.1.8-cp39-cp39-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 3.3 MB
  • Tags: CPython 3.9, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for fstd-0.1.8-cp39-cp39-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 40d188a39fa6eb382828fdcd524ccd042ad238c3bd4033c6b99eb2d043e6a3d1
MD5 217c977f724cbd79db8bd3b1574f7f52
BLAKE2b-256 8ef994f1610fe2c7a4dd5c18f3569ae1ee24c48039c562e8a264585273623c0c

See more details on using hashes here.

Provenance

The following attestation bundles were made for fstd-0.1.8-cp39-cp39-macosx_11_0_arm64.whl:

Publisher: wheels.yml on MouJieQin/fstd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page