Created
November 20, 2024 09:20
-
-
Save yazdipour/8b4d00d2d172c37f7d1a7bafcd7cb914 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from notion_client import Client | |
from typing import List, Optional | |
import ollama | |
import json | |
database_id = "...." | |
notion_token = "secret_...." | |
llm_model = 'llama3.2' | |
llm_model = 'qwen2.5' | |
class FlashCard: | |
def __init__( | |
self, | |
word: str, | |
bedeutung: str, | |
example: str, | |
word_type: str, | |
level: str, | |
artikel: Optional[str] = None, | |
plural: Optional[str] = None, | |
perfekt: Optional[str] = None, | |
synonyms: Optional[str] = None, | |
antonyms: Optional[str] = None, | |
tags: Optional[List[str]] = None | |
): | |
self.word = word | |
self.bedeutung = bedeutung | |
self.example = example | |
self.word_type = word_type | |
self.level = level | |
self.artikel = artikel | |
self.plural = plural | |
self.perfekt = perfekt | |
self.synonyms = synonyms | |
self.antonyms = antonyms | |
self.tags = tags or [] | |
def create_flashcard(notion: Client, database_id: str, card: FlashCard) -> dict: | |
properties = { | |
"Input": { | |
"title": [{"text": {"content": card.word}}] | |
}, | |
"Bedeutung": { | |
"rich_text": [{"text": {"content": card.bedeutung}}] | |
}, | |
"Example": { | |
"rich_text": [{"text": {"content": card.example}}] | |
}, | |
"Type": { | |
"select": {"name": card.word_type} | |
}, | |
"Level": { | |
"select": {"name": card.level} | |
} | |
} | |
# Add optional properties if they exist | |
if card.artikel: | |
properties["Artikel"] = {"select": {"name": card.artikel}} | |
if card.plural: | |
properties["Plural"] = {"rich_text": [{"text": {"content": card.plural}}]} | |
if card.perfekt: | |
properties["Perfekt (v)"] = {"rich_text": [{"text": {"content": card.perfekt}}]} | |
if card.synonyms: | |
properties["Synonyms"] = {"rich_text": [{"text": {"content": card.synonyms}}]} | |
if card.antonyms: | |
properties["Antonyms "] = {"rich_text": [{"text": {"content": card.antonyms}}]} | |
if card.tags: | |
properties["Tag"] = {"multi_select": [{"name": tag} for tag in card.tags]} | |
return notion.pages.create(parent={"database_id": database_id}, properties=properties) | |
def get_word_info_from_ollama(llm_model: str, word: str) -> dict: | |
prompt = f"""Create a German language flashcard for the sentence or word "{word}". | |
Return a JSON object with these fields and only the json nothing else: | |
- meaning [str](English meaning) | |
- example [str](example sentence in German with english translation in brackets) | |
- type [str]("Verb" or "Wortschatz" or "Satz" - Dont use anything else) | |
- level [str](A1, A2, B1, B2, C1) | |
- artikel [str](der/die/das if noun) | |
- plural [str](plural form if noun) | |
- perfekt [str](perfekt form if verb) | |
- synonyms [str](one synonyms in german) | |
- antonyms [str](one antonyms in german) | |
- tag [str]("ADV" if adverb, "ADJ" if adjective, "DATIV Verb" if it always creates dativ or "Redemittel". Choose one or Leave empty if none apply) | |
Ensure the response is valid JSON format.""" | |
client = ollama.Client(host='http://localhost:11434') | |
response = client.chat(model=llm_model, messages=[ | |
{ | |
'role': 'user', | |
'content': prompt | |
} | |
]) | |
# Extract JSON from response | |
json_str = response['message']['content'] | |
# print(json_str) | |
# Find JSON content between curly braces | |
start = json_str.find('{') | |
end = json_str.rfind('}') + 1 | |
if start >= 0 and end > 0: | |
json_str = json_str[start:end] | |
try: | |
return json.loads(json_str) | |
except json.JSONDecodeError: | |
print("Failed to parse JSON. Raw response:") | |
print(json_str) | |
return {} | |
def main(): | |
notion = Client(auth= notion_token) | |
while True: | |
# Get word from user | |
word = input("Enter the German word (or type 'q' to quit): ") | |
if word.lower() == 'q': | |
print("Exiting the flashcard creator.") | |
break | |
# Get word information from Ollama | |
word_info = get_word_info_from_ollama(llm_model, word) | |
if word_info == {}: | |
print("❌ Skipping") | |
continue | |
# Ensure tags is a list | |
tags = word_info.get('tag') | |
if isinstance(tags, str) and tags != '': | |
tags = [tags] | |
elif tags is None: | |
tags = [] | |
# if word is empty continue to next iteration | |
if word == '' or word_info.get('meaning') == '': | |
print("❌ Skipping") | |
continue | |
# Print word_info beautifully | |
print("\nFlashcard data:") | |
print(json.dumps(word_info, indent=2, ensure_ascii=False)) | |
print() | |
# Create flashcard with Ollama response | |
flashcard = FlashCard( | |
word=word, | |
bedeutung=word_info.get('meaning', ''), | |
example=word_info.get('example', ''), | |
word_type=word_info.get('type', 'Wortschatz'), | |
level=word_info.get('level', 'A1'), | |
artikel=word_info.get('artikel'), | |
plural=word_info.get('plural'), | |
perfekt=word_info.get('perfekt'), | |
synonyms=word_info.get('synonyms'), | |
antonyms=word_info.get('antonyms'), | |
tags=tags | |
) | |
response = create_flashcard(notion, database_id, flashcard) | |
print(f"🚀 Notion page URL: {response.get('url')}\n") | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment