├── .gitignore ├── LICENSE ├── README.md ├── kgsearch.gif ├── kgsearch ├── __init__.py ├── __version__.py ├── app │ ├── __init__.py │ └── app.py ├── data │ ├── .gitkeep │ ├── data.csv │ └── metadata.json └── web │ ├── app.html │ └── style.css ├── requirements.txt └── setup.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | *.pkl 7 | 8 | *.DS_Store 9 | 10 | # C extensions 11 | *.so 12 | 13 | # Distribution / packaging 14 | .Python 15 | build/ 16 | develop-eggs/ 17 | dist/ 18 | downloads/ 19 | eggs/ 20 | .eggs/ 21 | lib/ 22 | lib64/ 23 | parts/ 24 | sdist/ 25 | var/ 26 | wheels/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | cover/ 57 | 58 | # Translations 59 | *.mo 60 | *.pot 61 | 62 | # Django stuff: 63 | *.log 64 | local_settings.py 65 | db.sqlite3 66 | db.sqlite3-journal 67 | 68 | # Flask stuff: 69 | instance/ 70 | .webassets-cache 71 | 72 | # Scrapy stuff: 73 | .scrapy 74 | 75 | # Sphinx documentation 76 | docs/_build/ 77 | 78 | # PyBuilder 79 | .pybuilder/ 80 | target/ 81 | 82 | # Jupyter Notebook 83 | .ipynb_checkpoints 84 | 85 | # IPython 86 | profile_default/ 87 | ipython_config.py 88 | 89 | # pyenv 90 | # For a library or package, you might want to ignore these files since the code is 91 | # intended to run in multiple environments; otherwise, check them in: 92 | # .python-version 93 | 94 | # pipenv 95 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 96 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 97 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 98 | # install all needed dependencies. 99 | #Pipfile.lock 100 | 101 | # poetry 102 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 103 | # This is especially recommended for binary packages to ensure reproducibility, and is more 104 | # commonly ignored for libraries. 105 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 106 | #poetry.lock 107 | 108 | # pdm 109 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 110 | #pdm.lock 111 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 112 | # in version control. 113 | # https://pdm.fming.dev/#use-with-ide 114 | .pdm.toml 115 | 116 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 117 | __pypackages__/ 118 | 119 | # Celery stuff 120 | celerybeat-schedule 121 | celerybeat.pid 122 | 123 | # SageMath parsed files 124 | *.sage.py 125 | 126 | # Environments 127 | .env 128 | .venv 129 | env/ 130 | venv/ 131 | ENV/ 132 | env.bak/ 133 | venv.bak/ 134 | 135 | # Spyder project settings 136 | .spyderproject 137 | .spyproject 138 | 139 | # Rope project settings 140 | .ropeproject 141 | 142 | # mkdocs documentation 143 | /site 144 | 145 | # mypy 146 | .mypy_cache/ 147 | .dmypy.json 148 | dmypy.json 149 | 150 | # Pyre type checker 151 | .pyre/ 152 | 153 | # pytype static type analyzer 154 | .pytype/ 155 | 156 | # Cython debug symbols 157 | cython_debug/ 158 | 159 | # PyCharm 160 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 161 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 162 | # and can be added to the global gitignore or merged into this file. For a more nuclear 163 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 164 | #.idea/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Raphael Sourty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

KGSearch

3 |
4 | 5 | ![](kgsearch.gif) 6 | 7 | KGSearch is a minimalist tool for searching and viewing entities in a graph and is dedicated to a local environment. The application provides a Python client with three distinct terminal commands: `add, start, open`. The application default proposes to search through the knowledge graph [Countries](https://www.aaai.org/ocs/index.php/SSS/SSS15/paper/view/10257/10026). You can explore the borders we must cross to get from one country to another and see how small the 🌍 is. 8 | 9 | ## Installation 10 | 11 | ```sh 12 | pip install git+https://github.com/raphaelsty/kgsearch 13 | ``` 14 | 15 | ## ✅ Quick Start 16 | 17 | The `start` command starts the API and opens the user interface: 18 | 19 | ```sh 20 | kg start 21 | ``` 22 | 23 | ## ⭐️ Query 24 | 25 | KGSearch suggests performing multiple queries via the `;` separator. 26 | 27 | The query `france;germany;china` will be divided into three subqueries `france`, `germany`, and `china` to visualize the interactions between the entities of our choice. 28 | 29 | The `top K` field allows selecting the number of candidate entities retrieved by the search engine (1 by default). 30 | 31 | The `neighbours` field selects the number of neighbors to be displayed (1 by default). 32 | 33 | The `prune` field removes entities that have fewer than `prune` connections to other entities (1 by default). 34 | 35 | ## 🤖 Custom KG 36 | 37 | We can add our graph to KGSearch via the command: 38 | 39 | ```sh 40 | kg add -f data.csv 41 | ``` 42 | 43 | The graph must be saved in CSV format and structured as triples (head, relation, tail) with a comma separator and without column names. Here is an example of a compatible CSV file: 44 | 45 | ```sh 46 | senegal,neighbor,gambia 47 | senegal,neighbor,mauritania 48 | senegal,neighbor,mali 49 | senegal,neighbor,guinea-bissau 50 | senegal,neighbor,guinea 51 | ``` 52 | 53 | We can also add custom metadata for each entity to be displayed in the user interface using `meta -f`: 54 | 55 | ```sh 56 | kg meta -f metadata.json 57 | ``` 58 | 59 | where the `metadata.json` file has the label of the entity as a key and a set of characteristics: 60 | 61 | ```json 62 | { 63 | "senegal": {"url": "https://en.wikipedia.org/wiki/senegal"}, 64 | "gambia": {"url": "https://en.wikipedia.org/wiki/gambia"}, 65 | "mauritania": {"url": "https://en.wikipedia.org/wiki/gambia"}, 66 | "mali": {"url": "https://en.wikipedia.org/wiki/mali"}, 67 | } 68 | ``` 69 | 70 | ## 📑 Notes 71 | 72 | If you have already started the application, you can reopen a window with the open command: 73 | 74 | ```sh 75 | kg open 76 | ``` 77 | 78 | The library [Cherche](https://github.com/raphaelsty/cherche) provides the entity search engine. KGSearch relies on a local flask API. The user interface is developed in React and uses the [3D Force-Directed Graph](https://github.com/vasturiano/3d-force-graph) library. -------------------------------------------------------------------------------- /kgsearch.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphaelsty/kgsearch/64dc6117e11ca689d7df8dc6635ec1798d895de3/kgsearch.gif -------------------------------------------------------------------------------- /kgsearch/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import webbrowser 3 | 4 | import click 5 | from rich import print 6 | 7 | from .app import Search, create_app, save_metadata 8 | 9 | __all__ = ["app"] 10 | 11 | path = os.path.abspath(os.path.dirname(__file__)) 12 | 13 | 14 | @click.command("start", short_help="Start the app") 15 | @click.argument("arg", type=str) 16 | @click.option("-f", help="Csv file with triples.") 17 | def start(arg, f): 18 | 19 | if arg == "start": 20 | # lsof -i:9200 21 | # lsof -i:5000 22 | # kill -9 23 | 24 | app = create_app() 25 | 26 | print("🎉 Starting the app.") 27 | webbrowser.open(os.path.join("file://" + path, "web/app.html")) 28 | app.run() 29 | 30 | elif arg == "add": 31 | Search(file=f).save(path=os.path.join(path, "data/search.pkl")) 32 | 33 | elif arg == "meta": 34 | save_metadata(origin=f, source=os.path.join(path, "data/metadata.json")) 35 | 36 | elif arg == "open": 37 | print("😎 Opening web.") 38 | webbrowser.open(os.path.join("file://" + path, "web/app.html")) 39 | -------------------------------------------------------------------------------- /kgsearch/__version__.py: -------------------------------------------------------------------------------- 1 | VERSION = (0, 0, 1) 2 | 3 | __version__ = ".".join(map(str, VERSION)) 4 | -------------------------------------------------------------------------------- /kgsearch/app/__init__.py: -------------------------------------------------------------------------------- 1 | from .app import Search, create_app, save_metadata 2 | 3 | __all__ = ["Search", "create_app", "save_metadata"] 4 | -------------------------------------------------------------------------------- /kgsearch/app/app.py: -------------------------------------------------------------------------------- 1 | import collections 2 | import json 3 | import os 4 | import pathlib 5 | import pickle 6 | from functools import lru_cache 7 | 8 | import pandas as pd 9 | from cherche import retrieve 10 | from flask import Flask 11 | from flask_cors import CORS, cross_origin 12 | from sklearn.feature_extraction.text import TfidfVectorizer 13 | 14 | __all__ = ["Search", "create_app", "save_metadata"] 15 | 16 | 17 | def save_metadata(origin, source): 18 | """Export metadata to the library.""" 19 | with open(origin, "r") as f: 20 | metadata = json.load(f) 21 | 22 | with open(source, "w") as f: 23 | json.dump(metadata, f, indent=4) 24 | 25 | 26 | class Search: 27 | """Search over KG.""" 28 | 29 | def __init__(self, file: str) -> None: 30 | 31 | self.colors = ["#00A36C", "#9370DB", "#bbae98", "#7393B3", "#677179", "#318ce7", "#088F8F"] 32 | self.metadata = {} 33 | 34 | triples = pd.read_csv(file, header=None, sep=",") 35 | 36 | documents = [ 37 | {"key": key, "label": label} 38 | for key, label in pd.concat([triples[0], triples[2]], axis="rows") 39 | .drop_duplicates(keep="first") 40 | .reset_index(drop=True) 41 | .to_dict() 42 | .items() 43 | ] 44 | 45 | self.retriever = ( 46 | retrieve.TfIdf( 47 | key="key", 48 | on="label", 49 | documents=documents, 50 | tfidf=TfidfVectorizer(lowercase=True, ngram_range=(3, 7), analyzer="char"), 51 | k=30, 52 | ) 53 | + documents 54 | ) 55 | 56 | self.triples = collections.defaultdict(tuple) 57 | self.relations = collections.defaultdict(list) 58 | 59 | for h, r, t in triples.to_records(index=False).tolist(): 60 | self.triples[h] += tuple([t]) 61 | self.triples[t] += tuple([h]) 62 | self.relations[f"{h}_{t}"].append(r) 63 | 64 | self.explore.cache_clear() 65 | 66 | def save(self, path): 67 | """Save the search object.""" 68 | with open(path, "wb") as f: 69 | pickle.dump(self, f) 70 | return self 71 | 72 | def load_metadata(self, path): 73 | """Load metadata""" 74 | with open(path, "r") as f: 75 | self.metadata = json.load(f) 76 | return self 77 | 78 | @lru_cache(maxsize=10000) 79 | def explore(self, entities, neighbours, entity, depth, max_depth): 80 | depth += 1 81 | 82 | for neighbour in neighbours: 83 | 84 | entities += tuple([tuple([entity, neighbour])]) 85 | 86 | if depth < max_depth: 87 | 88 | entities = self.explore( 89 | entities=entities, 90 | neighbours=self.triples.get(neighbour, tuple([])), 91 | entity=neighbour, 92 | depth=depth, 93 | max_depth=max_depth, 94 | ) 95 | 96 | return entities 97 | 98 | def __call__(self, query: str, k: int, n: int, p: int): 99 | nodes, links = [], [] 100 | entities, h_r_t = {}, {} 101 | prune = collections.defaultdict(int) 102 | 103 | candidates, seen = [], {} 104 | for q in query.split(";"): 105 | answer = self.retriever(q.strip())[: int(k)] 106 | for candidate in answer: 107 | if candidate["label"] not in seen: 108 | candidates.append(candidate) 109 | seen[candidate["label"]] = True 110 | 111 | for group, e in enumerate(candidates): 112 | 113 | e = e["label"] 114 | 115 | nodes.append( 116 | { 117 | "id": e, 118 | "group": group, 119 | "color": "#960018", 120 | "fontWeight": "bold", 121 | "metadata": self.metadata.get(e, {}), 122 | } 123 | ) 124 | 125 | entities[e] = True 126 | 127 | for group, e in enumerate(candidates): 128 | 129 | e = e["label"] 130 | color = self.colors[group % len(self.colors)] 131 | match = self.explore( 132 | entities=tuple([]), neighbours=self.triples[e], entity=e, depth=0, max_depth=n 133 | ) 134 | 135 | for h, t in list(match): 136 | 137 | if h not in entities: 138 | nodes.append( 139 | { 140 | "id": h, 141 | "group": group, 142 | "color": color, 143 | "metadata": self.metadata.get(h, {}), 144 | } 145 | ) 146 | entities[h] = True 147 | 148 | if t not in entities: 149 | nodes.append( 150 | { 151 | "id": t, 152 | "group": group, 153 | "color": color, 154 | "metadata": self.metadata.get(t, {}), 155 | } 156 | ) 157 | entities[t] = True 158 | 159 | for r in self.relations[f"{h}_{t}"]: 160 | if f"{h}_{r}_{t}" not in h_r_t: 161 | links.append({"source": h, "target": t, "value": 1, "relation": r}) 162 | h_r_t[f"{h}_{r}_{t}"] = True 163 | prune[h] += 1 164 | prune[t] += 1 165 | 166 | for r in self.relations[f"{t}_{h}"]: 167 | if f"{t}_{r}_{h}" not in h_r_t: 168 | links.append({"source": t, "relation": r, "target": h, "value": 1}) 169 | h_r_t[f"{t}_{r}_{h}"] = True 170 | prune[h] += 1 171 | prune[t] += 1 172 | # Prune 173 | if p > 1: 174 | links = [ 175 | link for link in links if prune[link["source"]] >= p and prune[link["target"]] >= p 176 | ] 177 | 178 | nodes = [node for node in nodes if prune[node["id"]] >= p] 179 | 180 | return {"nodes": nodes, "links": links} 181 | 182 | 183 | def create_app(): 184 | app = Flask(__name__) 185 | app.config["JSONIFY_PRETTYPRINT_REGULAR"] = True 186 | app.config["CORS_HEADERS"] = "Content-Type" 187 | CORS(app, resources={r"/search/*": {"origins": "*"}}) 188 | 189 | @app.route("/search///

/", methods=["GET"]) 190 | @cross_origin() 191 | def get(k: int, n: int, p: int, query: str): 192 | 193 | path = pathlib.Path(__file__).parent.joinpath("./../data") 194 | 195 | if os.path.exists(os.path.join(path, "search.pkl")): 196 | with open(os.path.join(path, "search.pkl"), "rb") as f: 197 | search = pickle.load(f) 198 | else: 199 | search = Search(file=os.path.join(path, "data.csv")).save( 200 | os.path.join(path, "search.pkl") 201 | ) 202 | 203 | if os.path.exists(os.path.join(path, "metadata.json")): 204 | search = search.load_metadata(path=os.path.join(path, "metadata.json")) 205 | 206 | return json.dumps(search(query=query, k=int(k), n=int(n), p=int(p))) 207 | 208 | return app 209 | -------------------------------------------------------------------------------- /kgsearch/data/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raphaelsty/kgsearch/64dc6117e11ca689d7df8dc6635ec1798d895de3/kgsearch/data/.gitkeep -------------------------------------------------------------------------------- /kgsearch/data/data.csv: -------------------------------------------------------------------------------- 1 | slovakia,neighbor,ukraine 2 | slovakia,neighbor,hungary 3 | slovakia,neighbor,austria 4 | slovakia,neighbor,czechia 5 | slovakia,neighbor,poland 6 | niger,neighbor,algeria 7 | niger,neighbor,chad 8 | niger,neighbor,libya 9 | niger,neighbor,burkina_faso 10 | niger,neighbor,mali 11 | niger,neighbor,nigeria 12 | niger,neighbor,benin 13 | morocco,neighbor,western_sahara 14 | morocco,neighbor,spain 15 | morocco,neighbor,algeria 16 | senegal,neighbor,gambia 17 | senegal,neighbor,mauritania 18 | senegal,neighbor,mali 19 | senegal,neighbor,guinea-bissau 20 | senegal,neighbor,guinea 21 | equatorial_guinea,neighbor,gabon 22 | equatorial_guinea,neighbor,cameroon 23 | gibraltar,neighbor,spain 24 | liechtenstein,neighbor,switzerland 25 | liechtenstein,neighbor,austria 26 | venezuela,neighbor,brazil 27 | venezuela,neighbor,colombia 28 | venezuela,neighbor,guyana 29 | afghanistan,neighbor,pakistan 30 | afghanistan,neighbor,iran 31 | afghanistan,neighbor,turkmenistan 32 | afghanistan,neighbor,uzbekistan 33 | afghanistan,neighbor,china 34 | afghanistan,neighbor,tajikistan 35 | greece,neighbor,turkey 36 | greece,neighbor,albania 37 | greece,neighbor,macedonia 38 | greece,neighbor,bulgaria 39 | qatar,neighbor,saudi_arabia 40 | ecuador,neighbor,peru 41 | ecuador,neighbor,colombia 42 | yemen,neighbor,oman 43 | yemen,neighbor,saudi_arabia 44 | namibia,neighbor,south_africa 45 | namibia,neighbor,zambia 46 | namibia,neighbor,angola 47 | namibia,neighbor,botswana 48 | hong_kong,neighbor,china 49 | paraguay,neighbor,brazil 50 | paraguay,neighbor,argentina 51 | paraguay,neighbor,bolivia 52 | india,neighbor,afghanistan 53 | india,neighbor,bangladesh 54 | india,neighbor,myanmar 55 | india,neighbor,pakistan 56 | india,neighbor,nepal 57 | india,neighbor,bhutan 58 | india,neighbor,china 59 | india,neighbor,sri_lanka 60 | croatia,neighbor,hungary 61 | croatia,neighbor,serbia 62 | croatia,neighbor,montenegro 63 | croatia,neighbor,bosnia_and_herzegovina 64 | croatia,neighbor,slovenia 65 | ethiopia,neighbor,eritrea 66 | ethiopia,neighbor,sudan 67 | ethiopia,neighbor,djibouti 68 | ethiopia,neighbor,south_sudan 69 | ethiopia,neighbor,somalia 70 | ethiopia,neighbor,kenya 71 | republic_of_the_congo,neighbor,cameroon 72 | republic_of_the_congo,neighbor,dr_congo 73 | republic_of_the_congo,neighbor,angola 74 | republic_of_the_congo,neighbor,gabon 75 | republic_of_the_congo,neighbor,central_african_republic 76 | malaysia,neighbor,brunei 77 | malaysia,neighbor,indonesia 78 | malaysia,neighbor,thailand 79 | latvia,neighbor,belarus 80 | latvia,neighbor,lithuania 81 | latvia,neighbor,russia 82 | latvia,neighbor,estonia 83 | algeria,neighbor,mauritania 84 | algeria,neighbor,libya 85 | algeria,neighbor,tunisia 86 | algeria,neighbor,western_sahara 87 | algeria,neighbor,mali 88 | eritrea,neighbor,sudan 89 | eritrea,neighbor,djibouti 90 | bhutan,neighbor,china 91 | vatican_city,neighbor,italy 92 | saint_martin,neighbor,sint_maarten 93 | mali,neighbor,mauritania 94 | mali,neighbor,ivory_coast 95 | mali,neighbor,guinea 96 | mali,neighbor,burkina_faso 97 | mauritania,neighbor,western_sahara 98 | netherlands,neighbor,belgium 99 | netherlands,neighbor,germany 100 | swaziland,neighbor,south_africa 101 | swaziland,neighbor,mozambique 102 | macau,neighbor,china 103 | lesotho,neighbor,south_africa 104 | czechia,neighbor,austria 105 | czechia,neighbor,germany 106 | czechia,neighbor,poland 107 | monaco,neighbor,france 108 | gabon,neighbor,cameroon 109 | brazil,neighbor,suriname 110 | brazil,neighbor,peru 111 | brazil,neighbor,uruguay 112 | brazil,neighbor,french_guiana 113 | brazil,neighbor,colombia 114 | brazil,neighbor,guyana 115 | brazil,neighbor,argentina 116 | brazil,neighbor,bolivia 117 | botswana,neighbor,south_africa 118 | botswana,neighbor,zambia 119 | botswana,neighbor,zimbabwe 120 | uzbekistan,neighbor,kyrgyzstan 121 | uzbekistan,neighbor,kazakhstan 122 | uzbekistan,neighbor,turkmenistan 123 | uzbekistan,neighbor,tajikistan 124 | united_kingdom,neighbor,ireland 125 | papua_new_guinea,neighbor,indonesia 126 | moldova,neighbor,ukraine 127 | moldova,neighbor,romania 128 | chile,neighbor,argentina 129 | chile,neighbor,bolivia 130 | chile,neighbor,peru 131 | kazakhstan,neighbor,kyrgyzstan 132 | kazakhstan,neighbor,china 133 | kazakhstan,neighbor,russia 134 | kazakhstan,neighbor,turkmenistan 135 | mozambique,neighbor,south_africa 136 | mozambique,neighbor,tanzania 137 | mozambique,neighbor,malawi 138 | mozambique,neighbor,zimbabwe 139 | mozambique,neighbor,zambia 140 | guinea-bissau,neighbor,guinea 141 | bangladesh,neighbor,myanmar 142 | tunisia,neighbor,libya 143 | haiti,neighbor,dominican_republic 144 | bolivia,neighbor,argentina 145 | bolivia,neighbor,peru 146 | nigeria,neighbor,cameroon 147 | nigeria,neighbor,chad 148 | nigeria,neighbor,benin 149 | nepal,neighbor,china 150 | estonia,neighbor,russia 151 | cameroon,neighbor,central_african_republic 152 | cameroon,neighbor,chad 153 | south_korea,neighbor,north_korea 154 | palestine,neighbor,egypt 155 | palestine,neighbor,israel 156 | palestine,neighbor,jordan 157 | austria,neighbor,italy 158 | austria,neighbor,slovenia 159 | austria,neighbor,germany 160 | austria,neighbor,hungary 161 | austria,neighbor,switzerland 162 | benin,neighbor,togo 163 | benin,neighbor,burkina_faso 164 | burkina_faso,neighbor,ghana 165 | burkina_faso,neighbor,ivory_coast 166 | burkina_faso,neighbor,togo 167 | france,neighbor,italy 168 | france,neighbor,luxembourg 169 | france,neighbor,andorra 170 | france,neighbor,switzerland 171 | france,neighbor,germany 172 | france,neighbor,belgium 173 | france,neighbor,spain 174 | uganda,neighbor,dr_congo 175 | uganda,neighbor,tanzania 176 | uganda,neighbor,rwanda 177 | uganda,neighbor,south_sudan 178 | uganda,neighbor,kenya 179 | guinea,neighbor,liberia 180 | guinea,neighbor,sierra_leone 181 | guinea,neighbor,ivory_coast 182 | kyrgyzstan,neighbor,china 183 | kyrgyzstan,neighbor,tajikistan 184 | ivory_coast,neighbor,ghana 185 | ivory_coast,neighbor,liberia 186 | zambia,neighbor,angola 187 | zambia,neighbor,tanzania 188 | zambia,neighbor,malawi 189 | zambia,neighbor,zimbabwe 190 | zambia,neighbor,dr_congo 191 | bosnia_and_herzegovina,neighbor,montenegro 192 | bosnia_and_herzegovina,neighbor,serbia 193 | germany,neighbor,denmark 194 | germany,neighbor,poland 195 | germany,neighbor,luxembourg 196 | germany,neighbor,switzerland 197 | germany,neighbor,belgium 198 | iraq,neighbor,turkey 199 | iraq,neighbor,iran 200 | iraq,neighbor,kuwait 201 | iraq,neighbor,jordan 202 | iraq,neighbor,saudi_arabia 203 | iraq,neighbor,syria 204 | albania,neighbor,kosovo 205 | albania,neighbor,montenegro 206 | albania,neighbor,macedonia 207 | guyana,neighbor,suriname 208 | suriname,neighbor,french_guiana 209 | montenegro,neighbor,serbia 210 | montenegro,neighbor,kosovo 211 | poland,neighbor,ukraine 212 | poland,neighbor,belarus 213 | poland,neighbor,lithuania 214 | poland,neighbor,russia 215 | lebanon,neighbor,syria 216 | lebanon,neighbor,israel 217 | sweden,neighbor,finland 218 | sweden,neighbor,norway 219 | switzerland,neighbor,italy 220 | mexico,neighbor,united_states 221 | mexico,neighbor,guatemala 222 | mexico,neighbor,belize 223 | guatemala,neighbor,belize 224 | guatemala,neighbor,honduras 225 | guatemala,neighbor,el_salvador 226 | argentina,neighbor,uruguay 227 | rwanda,neighbor,burundi 228 | rwanda,neighbor,dr_congo 229 | rwanda,neighbor,tanzania 230 | cyprus,neighbor,united_kingdom 231 | mongolia,neighbor,china 232 | mongolia,neighbor,russia 233 | zimbabwe,neighbor,south_africa 234 | canada,neighbor,united_states 235 | dr_congo,neighbor,central_african_republic 236 | dr_congo,neighbor,angola 237 | dr_congo,neighbor,tanzania 238 | dr_congo,neighbor,south_sudan 239 | dr_congo,neighbor,burundi 240 | kosovo,neighbor,serbia 241 | kosovo,neighbor,macedonia 242 | south_sudan,neighbor,central_african_republic 243 | south_sudan,neighbor,sudan 244 | south_sudan,neighbor,kenya 245 | vietnam,neighbor,china 246 | vietnam,neighbor,cambodia 247 | vietnam,neighbor,laos 248 | luxembourg,neighbor,belgium 249 | ghana,neighbor,togo 250 | tajikistan,neighbor,china 251 | malawi,neighbor,tanzania 252 | burundi,neighbor,tanzania 253 | kenya,neighbor,tanzania 254 | kenya,neighbor,somalia 255 | iran,neighbor,turkey 256 | iran,neighbor,turkmenistan 257 | iran,neighbor,pakistan 258 | iran,neighbor,azerbaijan 259 | iran,neighbor,armenia 260 | italy,neighbor,san_marino 261 | italy,neighbor,slovenia 262 | united_arab_emirates,neighbor,oman 263 | united_arab_emirates,neighbor,saudi_arabia 264 | nicaragua,neighbor,costa_rica 265 | nicaragua,neighbor,honduras 266 | andorra,neighbor,spain 267 | honduras,neighbor,el_salvador 268 | central_african_republic,neighbor,chad 269 | central_african_republic,neighbor,sudan 270 | kuwait,neighbor,saudi_arabia 271 | bulgaria,neighbor,turkey 272 | bulgaria,neighbor,romania 273 | bulgaria,neighbor,serbia 274 | bulgaria,neighbor,macedonia 275 | thailand,neighbor,cambodia 276 | thailand,neighbor,myanmar 277 | thailand,neighbor,laos 278 | somalia,neighbor,djibouti 279 | chad,neighbor,libya 280 | chad,neighbor,south_sudan 281 | saudi_arabia,neighbor,jordan 282 | saudi_arabia,neighbor,oman 283 | azerbaijan,neighbor,turkey 284 | azerbaijan,neighbor,georgia 285 | azerbaijan,neighbor,russia 286 | azerbaijan,neighbor,armenia 287 | peru,neighbor,colombia 288 | ukraine,neighbor,romania 289 | ukraine,neighbor,belarus 290 | ukraine,neighbor,hungary 291 | ukraine,neighbor,russia 292 | pakistan,neighbor,china 293 | armenia,neighbor,turkey 294 | armenia,neighbor,georgia 295 | lithuania,neighbor,belarus 296 | lithuania,neighbor,russia 297 | slovenia,neighbor,hungary 298 | macedonia,neighbor,serbia 299 | serbia,neighbor,romania 300 | serbia,neighbor,hungary 301 | russia,neighbor,georgia 302 | russia,neighbor,norway 303 | russia,neighbor,finland 304 | russia,neighbor,north_korea 305 | russia,neighbor,belarus 306 | russia,neighbor,china 307 | north_korea,neighbor,china 308 | syria,neighbor,turkey 309 | syria,neighbor,israel 310 | syria,neighbor,jordan 311 | timor-leste,neighbor,indonesia 312 | georgia,neighbor,turkey 313 | finland,neighbor,norway 314 | laos,neighbor,china 315 | laos,neighbor,cambodia 316 | laos,neighbor,myanmar 317 | colombia,neighbor,panama 318 | egypt,neighbor,sudan 319 | egypt,neighbor,israel 320 | egypt,neighbor,libya 321 | china,neighbor,myanmar 322 | jordan,neighbor,israel 323 | costa_rica,neighbor,panama 324 | sudan,neighbor,chad 325 | sudan,neighbor,libya 326 | sierra_leone,neighbor,liberia 327 | hungary,neighbor,romania 328 | spain,neighbor,portugal 329 | -------------------------------------------------------------------------------- /kgsearch/data/metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "slovakia": { 3 | "url": "https://en.wikipedia.org/wiki/slovakia" 4 | }, 5 | "niger": { 6 | "url": "https://en.wikipedia.org/wiki/niger" 7 | }, 8 | "morocco": { 9 | "url": "https://en.wikipedia.org/wiki/morocco" 10 | }, 11 | "senegal": { 12 | "url": "https://en.wikipedia.org/wiki/senegal" 13 | }, 14 | "equatorial_guinea": { 15 | "url": "https://en.wikipedia.org/wiki/equatorial_guinea" 16 | }, 17 | "gibraltar": { 18 | "url": "https://en.wikipedia.org/wiki/gibraltar" 19 | }, 20 | "liechtenstein": { 21 | "url": "https://en.wikipedia.org/wiki/liechtenstein" 22 | }, 23 | "venezuela": { 24 | "url": "https://en.wikipedia.org/wiki/venezuela" 25 | }, 26 | "afghanistan": { 27 | "url": "https://en.wikipedia.org/wiki/afghanistan" 28 | }, 29 | "greece": { 30 | "url": "https://en.wikipedia.org/wiki/greece" 31 | }, 32 | "qatar": { 33 | "url": "https://en.wikipedia.org/wiki/qatar" 34 | }, 35 | "ecuador": { 36 | "url": "https://en.wikipedia.org/wiki/ecuador" 37 | }, 38 | "yemen": { 39 | "url": "https://en.wikipedia.org/wiki/yemen" 40 | }, 41 | "namibia": { 42 | "url": "https://en.wikipedia.org/wiki/namibia" 43 | }, 44 | "hong_kong": { 45 | "url": "https://en.wikipedia.org/wiki/hong_kong" 46 | }, 47 | "paraguay": { 48 | "url": "https://en.wikipedia.org/wiki/paraguay" 49 | }, 50 | "india": { 51 | "url": "https://en.wikipedia.org/wiki/india" 52 | }, 53 | "croatia": { 54 | "url": "https://en.wikipedia.org/wiki/croatia" 55 | }, 56 | "ethiopia": { 57 | "url": "https://en.wikipedia.org/wiki/ethiopia" 58 | }, 59 | "republic_of_the_congo": { 60 | "url": "https://en.wikipedia.org/wiki/republic_of_the_congo" 61 | }, 62 | "malaysia": { 63 | "url": "https://en.wikipedia.org/wiki/malaysia" 64 | }, 65 | "latvia": { 66 | "url": "https://en.wikipedia.org/wiki/latvia" 67 | }, 68 | "algeria": { 69 | "url": "https://en.wikipedia.org/wiki/algeria" 70 | }, 71 | "eritrea": { 72 | "url": "https://en.wikipedia.org/wiki/eritrea" 73 | }, 74 | "bhutan": { 75 | "url": "https://en.wikipedia.org/wiki/bhutan" 76 | }, 77 | "vatican_city": { 78 | "url": "https://en.wikipedia.org/wiki/vatican_city" 79 | }, 80 | "saint_martin": { 81 | "url": "https://en.wikipedia.org/wiki/saint_martin" 82 | }, 83 | "mali": { 84 | "url": "https://en.wikipedia.org/wiki/mali" 85 | }, 86 | "mauritania": { 87 | "url": "https://en.wikipedia.org/wiki/mauritania" 88 | }, 89 | "netherlands": { 90 | "url": "https://en.wikipedia.org/wiki/netherlands" 91 | }, 92 | "swaziland": { 93 | "url": "https://en.wikipedia.org/wiki/swaziland" 94 | }, 95 | "macau": { 96 | "url": "https://en.wikipedia.org/wiki/macau" 97 | }, 98 | "lesotho": { 99 | "url": "https://en.wikipedia.org/wiki/lesotho" 100 | }, 101 | "czechia": { 102 | "url": "https://en.wikipedia.org/wiki/czechia" 103 | }, 104 | "monaco": { 105 | "url": "https://en.wikipedia.org/wiki/monaco" 106 | }, 107 | "gabon": { 108 | "url": "https://en.wikipedia.org/wiki/gabon" 109 | }, 110 | "brazil": { 111 | "url": "https://en.wikipedia.org/wiki/brazil" 112 | }, 113 | "botswana": { 114 | "url": "https://en.wikipedia.org/wiki/botswana" 115 | }, 116 | "uzbekistan": { 117 | "url": "https://en.wikipedia.org/wiki/uzbekistan" 118 | }, 119 | "united_kingdom": { 120 | "url": "https://en.wikipedia.org/wiki/united_kingdom" 121 | }, 122 | "papua_new_guinea": { 123 | "url": "https://en.wikipedia.org/wiki/papua_new_guinea" 124 | }, 125 | "moldova": { 126 | "url": "https://en.wikipedia.org/wiki/moldova" 127 | }, 128 | "chile": { 129 | "url": "https://en.wikipedia.org/wiki/chile" 130 | }, 131 | "kazakhstan": { 132 | "url": "https://en.wikipedia.org/wiki/kazakhstan" 133 | }, 134 | "mozambique": { 135 | "url": "https://en.wikipedia.org/wiki/mozambique" 136 | }, 137 | "guinea-bissau": { 138 | "url": "https://en.wikipedia.org/wiki/guinea-bissau" 139 | }, 140 | "bangladesh": { 141 | "url": "https://en.wikipedia.org/wiki/bangladesh" 142 | }, 143 | "tunisia": { 144 | "url": "https://en.wikipedia.org/wiki/tunisia" 145 | }, 146 | "haiti": { 147 | "url": "https://en.wikipedia.org/wiki/haiti" 148 | }, 149 | "bolivia": { 150 | "url": "https://en.wikipedia.org/wiki/bolivia" 151 | }, 152 | "nigeria": { 153 | "url": "https://en.wikipedia.org/wiki/nigeria" 154 | }, 155 | "nepal": { 156 | "url": "https://en.wikipedia.org/wiki/nepal" 157 | }, 158 | "estonia": { 159 | "url": "https://en.wikipedia.org/wiki/estonia" 160 | }, 161 | "cameroon": { 162 | "url": "https://en.wikipedia.org/wiki/cameroon" 163 | }, 164 | "south_korea": { 165 | "url": "https://en.wikipedia.org/wiki/south_korea" 166 | }, 167 | "palestine": { 168 | "url": "https://en.wikipedia.org/wiki/palestine" 169 | }, 170 | "austria": { 171 | "url": "https://en.wikipedia.org/wiki/austria" 172 | }, 173 | "benin": { 174 | "url": "https://en.wikipedia.org/wiki/benin" 175 | }, 176 | "burkina_faso": { 177 | "url": "https://en.wikipedia.org/wiki/burkina_faso" 178 | }, 179 | "france": { 180 | "url": "https://en.wikipedia.org/wiki/france" 181 | }, 182 | "uganda": { 183 | "url": "https://en.wikipedia.org/wiki/uganda" 184 | }, 185 | "guinea": { 186 | "url": "https://en.wikipedia.org/wiki/guinea" 187 | }, 188 | "kyrgyzstan": { 189 | "url": "https://en.wikipedia.org/wiki/kyrgyzstan" 190 | }, 191 | "ivory_coast": { 192 | "url": "https://en.wikipedia.org/wiki/ivory_coast" 193 | }, 194 | "zambia": { 195 | "url": "https://en.wikipedia.org/wiki/zambia" 196 | }, 197 | "bosnia_and_herzegovina": { 198 | "url": "https://en.wikipedia.org/wiki/bosnia_and_herzegovina" 199 | }, 200 | "germany": { 201 | "url": "https://en.wikipedia.org/wiki/germany" 202 | }, 203 | "iraq": { 204 | "url": "https://en.wikipedia.org/wiki/iraq" 205 | }, 206 | "albania": { 207 | "url": "https://en.wikipedia.org/wiki/albania" 208 | }, 209 | "guyana": { 210 | "url": "https://en.wikipedia.org/wiki/guyana" 211 | }, 212 | "suriname": { 213 | "url": "https://en.wikipedia.org/wiki/suriname" 214 | }, 215 | "montenegro": { 216 | "url": "https://en.wikipedia.org/wiki/montenegro" 217 | }, 218 | "poland": { 219 | "url": "https://en.wikipedia.org/wiki/poland" 220 | }, 221 | "lebanon": { 222 | "url": "https://en.wikipedia.org/wiki/lebanon" 223 | }, 224 | "sweden": { 225 | "url": "https://en.wikipedia.org/wiki/sweden" 226 | }, 227 | "switzerland": { 228 | "url": "https://en.wikipedia.org/wiki/switzerland" 229 | }, 230 | "mexico": { 231 | "url": "https://en.wikipedia.org/wiki/mexico" 232 | }, 233 | "guatemala": { 234 | "url": "https://en.wikipedia.org/wiki/guatemala" 235 | }, 236 | "argentina": { 237 | "url": "https://en.wikipedia.org/wiki/argentina" 238 | }, 239 | "rwanda": { 240 | "url": "https://en.wikipedia.org/wiki/rwanda" 241 | }, 242 | "cyprus": { 243 | "url": "https://en.wikipedia.org/wiki/cyprus" 244 | }, 245 | "mongolia": { 246 | "url": "https://en.wikipedia.org/wiki/mongolia" 247 | }, 248 | "zimbabwe": { 249 | "url": "https://en.wikipedia.org/wiki/zimbabwe" 250 | }, 251 | "canada": { 252 | "url": "https://en.wikipedia.org/wiki/canada" 253 | }, 254 | "dr_congo": { 255 | "url": "https://en.wikipedia.org/wiki/dr_congo" 256 | }, 257 | "kosovo": { 258 | "url": "https://en.wikipedia.org/wiki/kosovo" 259 | }, 260 | "south_sudan": { 261 | "url": "https://en.wikipedia.org/wiki/south_sudan" 262 | }, 263 | "vietnam": { 264 | "url": "https://en.wikipedia.org/wiki/vietnam" 265 | }, 266 | "luxembourg": { 267 | "url": "https://en.wikipedia.org/wiki/luxembourg" 268 | }, 269 | "ghana": { 270 | "url": "https://en.wikipedia.org/wiki/ghana" 271 | }, 272 | "tajikistan": { 273 | "url": "https://en.wikipedia.org/wiki/tajikistan" 274 | }, 275 | "malawi": { 276 | "url": "https://en.wikipedia.org/wiki/malawi" 277 | }, 278 | "burundi": { 279 | "url": "https://en.wikipedia.org/wiki/burundi" 280 | }, 281 | "kenya": { 282 | "url": "https://en.wikipedia.org/wiki/kenya" 283 | }, 284 | "iran": { 285 | "url": "https://en.wikipedia.org/wiki/iran" 286 | }, 287 | "italy": { 288 | "url": "https://en.wikipedia.org/wiki/italy" 289 | }, 290 | "united_arab_emirates": { 291 | "url": "https://en.wikipedia.org/wiki/united_arab_emirates" 292 | }, 293 | "nicaragua": { 294 | "url": "https://en.wikipedia.org/wiki/nicaragua" 295 | }, 296 | "andorra": { 297 | "url": "https://en.wikipedia.org/wiki/andorra" 298 | }, 299 | "honduras": { 300 | "url": "https://en.wikipedia.org/wiki/honduras" 301 | }, 302 | "central_african_republic": { 303 | "url": "https://en.wikipedia.org/wiki/central_african_republic" 304 | }, 305 | "kuwait": { 306 | "url": "https://en.wikipedia.org/wiki/kuwait" 307 | }, 308 | "bulgaria": { 309 | "url": "https://en.wikipedia.org/wiki/bulgaria" 310 | }, 311 | "thailand": { 312 | "url": "https://en.wikipedia.org/wiki/thailand" 313 | }, 314 | "somalia": { 315 | "url": "https://en.wikipedia.org/wiki/somalia" 316 | }, 317 | "chad": { 318 | "url": "https://en.wikipedia.org/wiki/chad" 319 | }, 320 | "saudi_arabia": { 321 | "url": "https://en.wikipedia.org/wiki/saudi_arabia" 322 | }, 323 | "azerbaijan": { 324 | "url": "https://en.wikipedia.org/wiki/azerbaijan" 325 | }, 326 | "peru": { 327 | "url": "https://en.wikipedia.org/wiki/peru" 328 | }, 329 | "ukraine": { 330 | "url": "https://en.wikipedia.org/wiki/ukraine" 331 | }, 332 | "pakistan": { 333 | "url": "https://en.wikipedia.org/wiki/pakistan" 334 | }, 335 | "armenia": { 336 | "url": "https://en.wikipedia.org/wiki/armenia" 337 | }, 338 | "lithuania": { 339 | "url": "https://en.wikipedia.org/wiki/lithuania" 340 | }, 341 | "slovenia": { 342 | "url": "https://en.wikipedia.org/wiki/slovenia" 343 | }, 344 | "macedonia": { 345 | "url": "https://en.wikipedia.org/wiki/macedonia" 346 | }, 347 | "serbia": { 348 | "url": "https://en.wikipedia.org/wiki/serbia" 349 | }, 350 | "russia": { 351 | "url": "https://en.wikipedia.org/wiki/russia" 352 | }, 353 | "north_korea": { 354 | "url": "https://en.wikipedia.org/wiki/north_korea" 355 | }, 356 | "syria": { 357 | "url": "https://en.wikipedia.org/wiki/syria" 358 | }, 359 | "timor-leste": { 360 | "url": "https://en.wikipedia.org/wiki/timor-leste" 361 | }, 362 | "georgia": { 363 | "url": "https://en.wikipedia.org/wiki/georgia" 364 | }, 365 | "finland": { 366 | "url": "https://en.wikipedia.org/wiki/finland" 367 | }, 368 | "laos": { 369 | "url": "https://en.wikipedia.org/wiki/laos" 370 | }, 371 | "colombia": { 372 | "url": "https://en.wikipedia.org/wiki/colombia" 373 | }, 374 | "egypt": { 375 | "url": "https://en.wikipedia.org/wiki/egypt" 376 | }, 377 | "china": { 378 | "url": "https://en.wikipedia.org/wiki/china" 379 | }, 380 | "jordan": { 381 | "url": "https://en.wikipedia.org/wiki/jordan" 382 | }, 383 | "costa_rica": { 384 | "url": "https://en.wikipedia.org/wiki/costa_rica" 385 | }, 386 | "sudan": { 387 | "url": "https://en.wikipedia.org/wiki/sudan" 388 | }, 389 | "sierra_leone": { 390 | "url": "https://en.wikipedia.org/wiki/sierra_leone" 391 | }, 392 | "hungary": { 393 | "url": "https://en.wikipedia.org/wiki/hungary" 394 | }, 395 | "spain": { 396 | "url": "https://en.wikipedia.org/wiki/spain" 397 | }, 398 | "libya": { 399 | "url": "https://en.wikipedia.org/wiki/libya" 400 | }, 401 | "western_sahara": { 402 | "url": "https://en.wikipedia.org/wiki/western_sahara" 403 | }, 404 | "gambia": { 405 | "url": "https://en.wikipedia.org/wiki/gambia" 406 | }, 407 | "turkmenistan": { 408 | "url": "https://en.wikipedia.org/wiki/turkmenistan" 409 | }, 410 | "turkey": { 411 | "url": "https://en.wikipedia.org/wiki/turkey" 412 | }, 413 | "oman": { 414 | "url": "https://en.wikipedia.org/wiki/oman" 415 | }, 416 | "south_africa": { 417 | "url": "https://en.wikipedia.org/wiki/south_africa" 418 | }, 419 | "angola": { 420 | "url": "https://en.wikipedia.org/wiki/angola" 421 | }, 422 | "myanmar": { 423 | "url": "https://en.wikipedia.org/wiki/myanmar" 424 | }, 425 | "sri_lanka": { 426 | "url": "https://en.wikipedia.org/wiki/sri_lanka" 427 | }, 428 | "djibouti": { 429 | "url": "https://en.wikipedia.org/wiki/djibouti" 430 | }, 431 | "brunei": { 432 | "url": "https://en.wikipedia.org/wiki/brunei" 433 | }, 434 | "indonesia": { 435 | "url": "https://en.wikipedia.org/wiki/indonesia" 436 | }, 437 | "belarus": { 438 | "url": "https://en.wikipedia.org/wiki/belarus" 439 | }, 440 | "sint_maarten": { 441 | "url": "https://en.wikipedia.org/wiki/sint_maarten" 442 | }, 443 | "belgium": { 444 | "url": "https://en.wikipedia.org/wiki/belgium" 445 | }, 446 | "uruguay": { 447 | "url": "https://en.wikipedia.org/wiki/uruguay" 448 | }, 449 | "french_guiana": { 450 | "url": "https://en.wikipedia.org/wiki/french_guiana" 451 | }, 452 | "ireland": { 453 | "url": "https://en.wikipedia.org/wiki/ireland" 454 | }, 455 | "romania": { 456 | "url": "https://en.wikipedia.org/wiki/romania" 457 | }, 458 | "tanzania": { 459 | "url": "https://en.wikipedia.org/wiki/tanzania" 460 | }, 461 | "dominican_republic": { 462 | "url": "https://en.wikipedia.org/wiki/dominican_republic" 463 | }, 464 | "israel": { 465 | "url": "https://en.wikipedia.org/wiki/israel" 466 | }, 467 | "togo": { 468 | "url": "https://en.wikipedia.org/wiki/togo" 469 | }, 470 | "liberia": { 471 | "url": "https://en.wikipedia.org/wiki/liberia" 472 | }, 473 | "denmark": { 474 | "url": "https://en.wikipedia.org/wiki/denmark" 475 | }, 476 | "norway": { 477 | "url": "https://en.wikipedia.org/wiki/norway" 478 | }, 479 | "united_states": { 480 | "url": "https://en.wikipedia.org/wiki/united_states" 481 | }, 482 | "belize": { 483 | "url": "https://en.wikipedia.org/wiki/belize" 484 | }, 485 | "el_salvador": { 486 | "url": "https://en.wikipedia.org/wiki/el_salvador" 487 | }, 488 | "cambodia": { 489 | "url": "https://en.wikipedia.org/wiki/cambodia" 490 | }, 491 | "san_marino": { 492 | "url": "https://en.wikipedia.org/wiki/san_marino" 493 | }, 494 | "panama": { 495 | "url": "https://en.wikipedia.org/wiki/panama" 496 | }, 497 | "portugal": { 498 | "url": "https://en.wikipedia.org/wiki/portugal" 499 | } 500 | } -------------------------------------------------------------------------------- /kgsearch/web/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |

4 | 5 |
6 | 7 |
8 | 9 | 10 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | -------------------------------------------------------------------------------- /kgsearch/web/style.css: -------------------------------------------------------------------------------- 1 | body { 2 | background-color: #FFFFF0; 3 | } 4 | 5 | #backsearch { 6 | position: fixed; 7 | z-index: 1; 8 | left: 0; 9 | top: 0; 10 | background-color: rgb(250, 249, 246, 0.8); 11 | width: 20%; 12 | 13 | margin: 3%; 14 | box-shadow: rgba(183, 148, 217, 0.4) -5px 5px, rgba(183, 148, 217, 0.3) -10px 10px, rgba(183, 148, 217, 0.2) -15px 15px, rgba(183, 148, 217, 0.1) -20px 20px, rgba(183, 148, 217, 0.05) -25px 25px; 15 | } 16 | 17 | #search { 18 | width: 80%; 19 | position: flex; 20 | margin-left: 10%; 21 | margin-right: 10%; 22 | margin-top: 5%; 23 | margin-bottom: 5%; 24 | font-family: 'Futura', sans-serif; 25 | font-weight: bolder; 26 | font-size: small; 27 | color: rgb(105, 105, 105, 0.8); 28 | padding-left: 3%; 29 | } 30 | 31 | #number { 32 | width: 20%; 33 | position: flex; 34 | margin-left: 10%; 35 | margin-right: 10%; 36 | margin-top: 0%; 37 | margin-bottom: 5%; 38 | font-family: 'Futura', sans-serif; 39 | font-weight: bolder; 40 | font-size: small; 41 | color: rgb(105, 105, 105, 0.8); 42 | padding-left: 3%; 43 | } 44 | 45 | .search_label { 46 | width: 80%; 47 | position: flex; 48 | margin-left: 10%; 49 | margin-right: 10%; 50 | margin-top: 5%; 51 | margin-bottom: 5%; 52 | 53 | } 54 | 55 | .label { 56 | font-family: 'Futura', sans-serif; 57 | font-weight: bolder; 58 | font-size: large; 59 | color: rgba(183, 148, 217, 0.4); 60 | width: 80%; 61 | position: flex; 62 | margin-left: 10%; 63 | margin-right: 10%; 64 | margin-top: 0%; 65 | margin-bottom: 2%; 66 | } 67 | 68 | #metadata { 69 | position: fixed; 70 | display: block; 71 | opacity: 1; 72 | z-index: 1; 73 | right: 0; 74 | top: 0; 75 | background-color: rgb(250, 249, 246, 0.1); 76 | width: 20%; 77 | margin-top: 3%; 78 | margin-right: 3%; 79 | } 80 | 81 | #field { 82 | font-family: 'Futura', sans-serif; 83 | font-weight: bold; 84 | font-size: small; 85 | color: rgb(105, 105, 105, 0.8); 86 | width: 80%; 87 | position: flex; 88 | margin-left: 10%; 89 | margin-right: 10%; 90 | margin-top: 5%; 91 | margin-bottom: 1%; 92 | overflow-wrap: break-word; 93 | } 94 | 95 | #content { 96 | font-family: 'Futura', sans-serif; 97 | font-weight: normal; 98 | font-size: small; 99 | color: rgb(105, 105, 105, 0.8); 100 | width: 80%; 101 | position: flex; 102 | margin-left: 10%; 103 | margin-right: 10%; 104 | overflow-wrap: break-word; 105 | margin-bottom: 5%; 106 | } 107 | 108 | #title { 109 | font-family: 'Futura', sans-serif; 110 | font-weight: normal; 111 | font-size: large; 112 | color: rgb(105, 105, 105, 0.8); 113 | width: 80%; 114 | position: flex; 115 | margin-left: 10%; 116 | margin-right: 10%; 117 | margin-bottom: 5%; 118 | margin-top: 5%; 119 | overflow-wrap: break-word; 120 | } -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | click == 8.1.7 2 | Flask == 3.0.3 3 | blinker == 1.8.2 4 | flask-cors == 4.0.1 5 | requests == 2.32.2 6 | cherche == 0.1.0 7 | pandas >= 1.4.2 8 | rich == 10.1.0 9 | Werkzeug==3.0.3 10 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from setuptools import find_packages, setup 4 | 5 | here = os.path.abspath(os.path.dirname(__file__)) 6 | 7 | with open("requirements.txt") as f: 8 | required = f.read().splitlines() 9 | 10 | setup( 11 | name="kgsearch", 12 | version="0.0.1", 13 | author="Raphael Sourty", 14 | author_email="raphael.sourty@gmail.com", 15 | description="Minimalist visual search engine for Knowledge Graph.", 16 | long_description_content_type="text/markdown", 17 | license="BSD-3", 18 | url="https://github.com/raphaelsty/kgsearch", 19 | package_data={ 20 | "kgsearch": ["web/app.html", "web/style.css", "data/data.csv", "data/metadata.json"] 21 | }, 22 | classifiers=[ 23 | "Programming Language :: Python :: 3", 24 | "License :: OSI Approved :: MIT License", 25 | "Operating System :: OS Independent", 26 | ], 27 | packages=find_packages(), 28 | include_package_data=True, 29 | install_requires=required, 30 | python_requires=">=3.7", 31 | entry_points={ 32 | "console_scripts": ["kg=kgsearch:start"], 33 | }, 34 | ) 35 | --------------------------------------------------------------------------------