Download utils/wikidata_utils.py from Jongmo/Prove_KCL: direct link, hf CLI and curl.
- Browser
- Download file 6.54 kB
-
https://huggingface.co/spaces/Jongmo/Prove_KCL/resolve/main/utils/wikidata_utils.py
- Command line
-
hf download hf://spaces/Jongmo/Prove_KCL/utils/wikidata_utils.py
-
curl -L -o wikidata_utils.py https://huggingface.co/spaces/Jongmo/Prove_KCL/resolve/main/utils/wikidata_utils.py
6.54 kB
| import json | |
| import random | |
| import uuid | |
| import numpy as np | |
| import time | |
| import requests | |
| import traceback | |
| import pdb | |
| import math | |
| import ast | |
| import pandas as pd | |
| import pickle | |
| from qwikidata.linked_data_interface import get_entity_dict_from_api | |
| from qwikidata.sparql import return_sparql_query_results | |
| from urllib3.exceptions import MaxRetryError, ConnectionError | |
| from qwikidata.linked_data_interface import LdiResponseNotOk | |
| import hashlib | |
| class CachedWikidataAPI(): | |
| def __init__(self, cache_path = 'entity_cache.p', save_every_x_queries=1): | |
| self.save_every_x_queries = save_every_x_queries | |
| self.x_queries_passed = 0 | |
| self.languages = ['en','fr','es','pt','pt-br','it','de'] | |
| self.cache_path = cache_path | |
| try: | |
| with open(self.cache_path,'rb') as f: | |
| self.entity_cache = pickle.load(f) | |
| except FileNotFoundError: | |
| self.entity_cache = {} | |
| def get_unique_id_from_str(self, my_str): | |
| return hashlib.md5(str.encode(my_str)).hexdigest() | |
| def save_entity_cache(self, force=False): | |
| if force: | |
| self.x_queries_passed = self.save_every_x_queries | |
| self.x_queries_passed = self.x_queries_passed+1 | |
| if self.x_queries_passed >= self.save_every_x_queries: | |
| with open(self.cache_path,'wb') as f: | |
| pickle.dump(self.entity_cache,f) | |
| self.x_queries_passed = 0 | |
| def get_entity(self, item_id): | |
| if item_id in self.entity_cache: | |
| return self.entity_cache[item_id] | |
| while True: | |
| try: | |
| entity = get_entity_dict_from_api(item_id) | |
| self.entity_cache[item_id] = entity | |
| self.save_entity_cache() | |
| return entity | |
| except (ConnectionError, MaxRetryError) as e: | |
| #traceback.print_exc() | |
| time.sleep(1) | |
| continue | |
| except LdiResponseNotOk: | |
| #traceback.print_exc() | |
| self.entity_cache[item_id] = 'deleted' | |
| self.save_entity_cache() | |
| return 'deleted' | |
| def get_label(self, item, non_language_set=False): | |
| if type(item) == str: | |
| entity = self.get_entity(item) | |
| if entity == 'deleted': | |
| return (entity, 'none') | |
| labels = entity['labels' if 'labels' in entity else 'lemmas'] | |
| elif type(item) == dict: | |
| if 'labels' in item: | |
| labels = item['labels'] | |
| elif 'lemmas' in item: | |
| labels = item['lemmas'] | |
| for l in self.languages: | |
| if l in labels: | |
| return (labels[l]['value'], l) | |
| if non_language_set: | |
| all_labels = list(labels.keys()) | |
| if len(all_labels)>0: | |
| return (labels[all_labels[0]]['value'], all_labels[0]) | |
| return ('no-label', 'none') | |
| def get_desc(self, item, non_language_set=False): | |
| if type(item) == str: | |
| entity = self.get_entity(item) | |
| if entity == 'deleted': | |
| return (entity, 'none') | |
| descriptions = entity['descriptions'] | |
| elif type(item) == dict: | |
| if 'descriptions' in item: | |
| descriptions = item['descriptions'] | |
| for l in self.languages: | |
| if l in descriptions: | |
| return (descriptions[l]['value'], l) | |
| if non_language_set: | |
| all_descriptions = list(descriptions.keys()) | |
| if len(all_descriptions)>0: | |
| return (descriptions[all_descriptions[0]]['value'], all_descriptions[0]) | |
| return ('no-desc', 'none') | |
| def get_alias(self, item, non_language_set=False): | |
| if type(item) == str: | |
| entity = self.get_entity(item) | |
| if entity == 'deleted': | |
| return ([entity], 'none') | |
| aliases = entity['aliases'] | |
| elif type(item) == dict: | |
| if 'aliases' in item: | |
| aliases = item['aliases'] | |
| for l in self.languages: | |
| if l in aliases: | |
| return ([alias['value'] for alias in aliases[l]], l) | |
| if non_language_set: | |
| all_aliases = list(aliases.keys()) | |
| if len(all_aliases)>0: | |
| return (aliases[all_aliases[0]]['value'], all_aliases[0]) | |
| return ([alias['value'] for alias in aliases[all_aliases[0]]], all_aliases[0]) | |
| return ('no-alias', 'none') | |
| def get_datatype(self, item): | |
| try: | |
| if type(item) == str: | |
| entity = self.get_entity(item) | |
| if entity == 'deleted': | |
| return entity | |
| datatype = entity['datatype'] | |
| elif type(item) == dict: | |
| datatype = item['datatype'] | |
| return datatype | |
| except KeyError: | |
| return 'none' | |
| def get_claim_values_of(self, item, property_id): | |
| if type(item) == str: | |
| entity = self.get_entity(item) | |
| if entity == 'deleted': | |
| return entity | |
| claims = entity['claims'] | |
| elif type(item) == dict: | |
| claims = item['claims'] | |
| if property_id in claims: | |
| instance_of_claims = claims[property_id] | |
| return [i['mainsnak']['datavalue']['value']['id'] for i in instance_of_claims] | |
| else: | |
| return [] | |
| def query_sparql_endpoint(self, sparql_query): | |
| sparql_query_id = self.get_unique_id_from_str(sparql_query) | |
| if sparql_query_id in self.entity_cache: | |
| return self.entity_cache[sparql_query_id] | |
| else: | |
| wikidata_sparql_url = 'https://query.wikidata.org/sparql' | |
| try: | |
| while True: | |
| res = requests.get(wikidata_sparql_url, params={"query": sparql_query, "format": "json"}) | |
| if res.status_code in (429,504): | |
| time.sleep(1) | |
| continue | |
| elif res.status_code == 200: | |
| res = res.json() | |
| self.entity_cache[sparql_query_id] = res | |
| self.save_entity_cache() | |
| return res | |
| else: | |
| print(res.status_code) | |
| raise Exception | |
| except json.JSONDecodeError as e: | |
| #pdb.set_trace() | |
| print(res, res.__dict__) | |
| raise e | |