{"id":170,"date":"2026-01-24T14:55:00","date_gmt":"2026-01-24T19:55:00","guid":{"rendered":"https:\/\/learnwithpatrick.casa\/?p=170"},"modified":"2026-01-24T14:55:00","modified_gmt":"2026-01-24T19:55:00","slug":"enriching-wanikani-dictionaries","status":"publish","type":"post","link":"https:\/\/learnwithpatrick.casa\/?p=170","title":{"rendered":"Enriching WaniKani Dictionaries"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Sometimes a short project hits you like a bolt of divine inspiration, and sometimes it hits you because you&#8217;re frustrated at your own failings and think there <em>must<\/em> be a programmatic fix for them. I started this as the latter, but I&#8217;ve since found peace with my failings since this didn&#8217;t really help it at all. In spite of that, I still feel this was a cool and useful project for other reasons.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>WaniKani<\/em> is a flashcard\/spaced repetition system for learning Japanese. It builds from radicals, to kanji, to vocabulary. When a &#8220;card&#8221; comes up, you get prompted to either type in how the characters or word is pronounced, or its meaning\/mnemonic. If you get a term correct, it will take longer for it to pop up in your reviews again, hence the &#8220;spaced repetition system&#8221;. If you get it incorrect, the timer restarts for that term. Once you&#8217;ve gotten a term correct a certain amount of times in a row you&#8217;re considered a &#8220;guru&#8221; &#8211; guru enough terms and you unlock the next level.<\/p>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"445\" height=\"310\" src=\"http:\/\/18.191.103.99\/wp-content\/uploads\/2026\/01\/image-1.png\" alt=\"\" class=\"wp-image-171\" srcset=\"https:\/\/learnwithpatrick.casa\/wp-content\/uploads\/2026\/01\/image-1.png 445w, https:\/\/learnwithpatrick.casa\/wp-content\/uploads\/2026\/01\/image-1-300x209.png 300w\" sizes=\"auto, (max-width: 445px) 100vw, 445px\" \/><figcaption class=\"wp-element-caption\">Screenshot of <em>WaniKani<\/em> in action<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">My frustration stemmed specifically from the vocabulary terms. I&#8217;ve been consuming Japanese pop culture for, well, a long time, and I have a decent handle on the language to start with, but reading has always been my weak point. In spite of that additional <s>baggage<\/s> knowledge, I found myself getting things wrong that I definitely knew, my definition was just slightly different from the way that <em>WaniKani<\/em> specifically wanted. They plan for this, though, and have a field where you can add your own synonyms!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I grumbled a bit every time this happened, but if I got the same term &#8220;wrong&#8221; multiple times, I&#8217;d add my own synonymical definition. As the vocabulary piled up, it went from a minor annoyance to upsetting me an embarrassing amount. So I did what anyone would do &#8211; I tried to think of a way to make it easier instead of just getting better!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Concepts of a Script<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\"><em>WaniKani<\/em> famously does not have any official apps. Tofugu, the parent company, consists of two people, so they have chosen to focus on their learning content and web application (which works just fine on mobile browsers). To offset this, they provide an API and blanket permission for anyone who wants to make an app, provided that they respect the paid subscription limitations.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">My problem was primarily with vocabulary terms and not the radicals or kanji &#8211; obviously it doesn&#8217;t make sense to go through the nearly 7000 vocabulary that I couldn&#8217;t already read to determine if I needed to add synonyms. So instead, the plan was to use a JP -> EN dictionary to look up the terms and programmatically add dictionary definitions to the user synonyms section. It should be a pretty simple script:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>get terms from wanikani API -> look up definitions from dictionary API -> compare definitions -> push new definitions to wanikani api<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Finding a Dictionary<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">There are a ton of nerds out there learning Japanese, which means a ton of tools have been created to help with the language learning journey. And yet, no simple JP -&gt; EN dictionary API! My JP dictionary of choice for the last decade+ has been <a href=\"http:\/\/www.jisho.org\" data-type=\"link\" data-id=\"www.jisho.org\">Jisho.org<\/a>, and while they do technically have an API, it is &#8220;not very good&#8221; <a href=\"https:\/\/jisho.org\/forum\/54fefc1f6e73340b1f160000-is-there-any-kind-of-search-api\">by their own admission<\/a>, and the only docs available are from that same thread (that hasn&#8217;t been updated in years). I did find a python package that scrapes Jisho and works as a de facto API, but there had to be a better way for this.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As it turns out, Jisho itself is primarily built on an open source dictionary named<a href=\"https:\/\/www.edrdg.org\/wiki\/index.php\/JMdict-EDICT_Dictionary_Project\" data-type=\"link\" data-id=\"https:\/\/www.edrdg.org\/wiki\/index.php\/JMdict-EDICT_Dictionary_Project\"> <em>JMDICT<\/em><\/a>. JMDICT is widely available as an XML document with some custom fields, but luckily for my own sanity, someone regularly parses the XML and repackages it as JSON on <a href=\"https:\/\/github.com\/scriptin\/jmdict-simplified\" data-type=\"link\" data-id=\"https:\/\/github.com\/scriptin\/jmdict-simplified\">GitHub<\/a>. With a dictionary sourced and downloaded, the next step was to grab the information I needed from it to build a lookup map. The JSON itself is just over 214k entries, weighing in around 100MB &#8211; large, but not too large to scan and build an index consisting of only term:[definitions] from to save to a pickle, or so I thought.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n  \"id\": \"1242170\",\n  \"kanji\": [\n    {\n      \"common\": true,\n      \"text\": \"\u8fd1\u3065\u304f\",\n      \"tags\": []\n    },\n    {\n      \"common\": true,\n      \"text\": \"\u8fd1\u4ed8\u304f\",\n      \"tags\": []\n    }\n  ],\n  \"kana\": [\n    {\n      \"common\": true,\n      \"text\": \"\u3061\u304b\u3065\u304f\",\n      \"tags\": [],\n      \"appliesToKanji\": &#91;\n        \"*\"\n      &#93;\n    },\n    {\n      \"common\": false,\n      \"text\": \"\u3061\u304b\u305a\u304f\",\n      \"tags\": &#91;\n        \"ik\"\n      &#93;,\n      \"appliesToKanji\": &#91;\n        \"\u8fd1\u4ed8\u304f\"\n      &#93;\n    }\n  ],\n  \"sense\": [\n    {\n      \"partOfSpeech\": &#91;\n        \"v5k\",\n        \"vi\"\n      &#93;,\n      \"appliesToKanji\": &#91;\n        \"*\"\n      &#93;,\n      \"appliesToKana\": &#91;\n        \"*\"\n      &#93;,\n      \"gloss\": &#91;\n        {\n          \"lang\": \"eng\",\n          \"gender\": null,\n          \"type\": null,\n          \"text\": \"to approach\"\n        },\n        {\n          \"lang\": \"eng\",\n          \"gender\": null,\n          \"type\": null,\n          \"text\": \"to draw near\"\n        },\n        {\n          \"lang\": \"eng\",\n          \"gender\": null,\n          \"type\": null,\n          \"text\": \"to get close\"\n        }\n      &#93;\n    },\n    {\n      \"partOfSpeech\": &#91;\n        \"v5k\",\n        \"vi\"\n      &#93;,\n      \"appliesToKanji\": &#91;\n        \"*\"\n      &#93;,\n      \"appliesToKana\": &#91;\n        \"*\"\n      &#93;,\n      \"gloss\": &#91;\n        {\n          \"lang\": \"eng\",\n          \"gender\": null,\n          \"type\": null,\n          \"text\": \"to get acquainted with\"\n        },\n        {\n          \"lang\": \"eng\",\n          \"gender\": null,\n          \"type\": null,\n          \"text\": \"to get closer to\"\n        },\n        {\n          \"lang\": \"eng\",\n          \"gender\": null,\n          \"type\": null,\n          \"text\": \"to get to know\"\n        }\n      &#93;\n    }\n  ]\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;1242170&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;kanji&quot;<\/span><span style=\"color: #D4D4D4\">: [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;common&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u8fd1\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;tags&quot;<\/span><span style=\"color: #D4D4D4\">: []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;common&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u8fd1\u4ed8\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;tags&quot;<\/span><span style=\"color: #D4D4D4\">: []<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  ],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;kana&quot;<\/span><span style=\"color: #D4D4D4\">: [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;common&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u3061\u304b\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;tags&quot;<\/span><span style=\"color: #D4D4D4\">: [],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;appliesToKanji&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;*&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;common&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u3061\u304b\u305a\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;tags&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;ik&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;appliesToKanji&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;\u8fd1\u4ed8\u304f&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  ],<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  <\/span><span style=\"color: #9CDCFE\">&quot;sense&quot;<\/span><span style=\"color: #D4D4D4\">: [<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;partOfSpeech&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;v5k&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;vi&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;appliesToKanji&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;*&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;appliesToKana&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;*&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;gloss&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;lang&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;eng&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;to approach&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;lang&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;eng&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;to draw near&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;lang&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;eng&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;to get close&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;partOfSpeech&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;v5k&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;vi&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;appliesToKanji&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;*&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;appliesToKana&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        <\/span><span style=\"color: #CE9178\">&quot;*&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;gloss&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;lang&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;eng&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;to get acquainted with&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;lang&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;eng&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;to get closer to&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;lang&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;eng&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">          <\/span><span style=\"color: #9CDCFE\">&quot;text&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;to get to know&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">        }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">    }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">  ]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Long story short, I tried several times to extract just the terms from the dictionary. I let it my script run for several hours and it appeared to hang, so I added some console output. The script was certainly adding terms, so I let it run overnight.. and it crashed. The next morning I realized how dumb I was being &#8211; I&#8217;m only going to need about 7000 of these for WaniKani, why would I ever build an index with 214k?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <em>WaniKani <\/em>API<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The next step would be to hit the <em>WaniKani<\/em> API to get that list of 7000 terms. WaniKani has<a href=\"https:\/\/docs.api.wanikani.com\/20170710\/\" data-type=\"link\" data-id=\"https:\/\/docs.api.wanikani.com\/20170710\/\"> <em>fantastic<\/em> API docs<\/a>, gratefully. Furthermore, getting the full list of vocab was as easy as hitting the <code>subjects<\/code> endpoint with the <code>types<\/code> parameter set to <code>vocabulary<\/code>. The API only return 1000 items at a time, but helpfully includes a <code>next_url<\/code> object when the results are paginated, so extracting all of them was a matter of doing a loop until that object is null.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>    url = base_url\n    #if it's over 1000 entries it paginates, so need a loop\n    while url:\n        response = requests.get(url, headers=headers,params=params).json()\n\n        #extract vocab from response\n        for item in response.get(\"data\",[]):\n          \"\"\"  \n            logic for extracting vocab\n          \"\"\"\n        #follow pagination due to 1000 api limit\n        url = response.get(\"pages\", {}).get(\"next_url\")<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme-darker\" style=\"background-color: #212121\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #EEFFFF\">    url <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> base_url<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #545454; font-style: italic\">#if it&#39;s over 1000 entries it paginates, so need a loop<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #89DDFF; font-style: italic\">while<\/span><span style=\"color: #EEFFFF\"> url<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        response <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> requests<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #82AAFF\">url<\/span><span style=\"color: #89DDFF\">,<\/span><span style=\"color: #82AAFF\"> <\/span><span style=\"color: #EEFFFF; font-style: italic\">headers<\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #82AAFF\">headers<\/span><span style=\"color: #89DDFF\">,<\/span><span style=\"color: #EEFFFF; font-style: italic\">params<\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #82AAFF\">params<\/span><span style=\"color: #89DDFF\">).<\/span><span style=\"color: #82AAFF\">json<\/span><span style=\"color: #89DDFF\">()<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #545454; font-style: italic\">#extract vocab from response<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF; font-style: italic\">for<\/span><span style=\"color: #EEFFFF\"> item <\/span><span style=\"color: #89DDFF; font-style: italic\">in<\/span><span style=\"color: #EEFFFF\"> response<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">data<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,[]):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">          <\/span><span style=\"color: #89DDFF; font-style: italic\">&quot;&quot;&quot;<\/span><span style=\"color: #545454; font-style: italic\">  <\/span><\/span>\n<span class=\"line\"><span style=\"color: #545454; font-style: italic\">            logic for extracting vocab<\/span><\/span>\n<span class=\"line\"><span style=\"color: #545454; font-style: italic\">          <\/span><span style=\"color: #89DDFF; font-style: italic\">&quot;&quot;&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #545454; font-style: italic\">#follow pagination due to 1000 api limit<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        url <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> response<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">pages<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><span style=\"color: #82AAFF\"> <\/span><span style=\"color: #89DDFF\">{}).<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">next_url<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">)<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Originally, this was built to grab a list of actual Japanese characters to send to the dictionary data to build a lookup index, so all I had it do was get the actual \u65e5\u672c\u8a9e from the terms (if I have to type <code>ensureAscii=false<\/code> one more time I might sob) and put them in an array, which worked great. By iterating over that array and searching the JMDICT data I was able to build an easy index to lookup a Japanese term and get its dictionary definitions. The performance was acceptable too &#8211; the list of 7000 terms took under a minute to build. I&#8217;m sure there was a more performant way to handle this, but at this scale it was absolutely fine.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">With the more simple index in hand, I was ready to look up the words on WaniKani again to compare their definitions and add dictionary definitions where needed, or so I thought. As it turns out, there&#8217;s no way to send Japanese to the WaniKani API and get the term you&#8217;re looking for back. The website supports a search so I had incorrectly assumed that the API would as well &#8211; in hindsight it makes sense that it wouldn&#8217;t, this is for building tools.. not a dictionary. Instead, to get a specific term&#8217;s meaning you have know the term&#8217;s ID, so you can hit the <code>subject\/&lt;id&gt;<\/code> endpoint.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This put me at a crossroads. The simple fix would be to just add the subject id to the existing index when I do the whole vocab query, then query the ID endpoint when needed for the definitions. This doubles my GETs though, and on the other hand, caching the information is both performant and good manners. Ultimately, I decided to save the whole vocab list to a pickle to not have to get any more for now. The pickle was just a list of the vocab objects; from that, I built a list for each item with the term, subject ID, and definition (from the dictionary, not WaniKani).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Dealing with Definitions<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">I knew that JMDICT holds definitions in an object named glosses[], but how does WaniKani? I&#8217;d need to look at WaniKani definitions, compare them to the dictionary definitions, and then add the delta back. I knew from using WaniKani that the definitions on the page weren&#8217;t necessarily the only definitions, and now I had the raw data from WaniKani to look at, so it was time to examine what was there:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#D4D4D4;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n   \"id\": 3434,\n   \"object\": \"vocabulary\",\n   \"url\": \"https:\/\/api.wanikani.com\/v2\/subjects\/3434\",\n   \"data_updated_at\": \"2025-11-18T14:31:49.951360Z\",\n   \"data\": {\n      \"created_at\": \"2012-07-22T23:28:45.447595Z\",\n      \"level\": 8,\n      \"slug\": \"\u8fd1\u3065\u304f\",\n      \"hidden_at\": null,\n      \"document_url\": \"https:\/\/www.wanikani.com\/vocabulary\/%E8%BF%91%E3%81%A5%E3%81%8F\",\n      \"characters\": \"\u8fd1\u3065\u304f\",\n      \"meanings\": &#91;\n         {\n            \"meaning\": \"To Get Close\",\n            \"primary\": true,\n            \"accepted_answer\": true\n         },\n         {\n            \"meaning\": \"To Approach\",\n            \"primary\": false,\n            \"accepted_answer\": true\n         },\n         {\n            \"meaning\": \"To Draw Near\",\n            \"primary\": false,\n            \"accepted_answer\": true\n         },\n         {\n            \"meaning\": \"To Near\",\n            \"primary\": false,\n            \"accepted_answer\": true\n         },\n         {\n            \"meaning\": \"To Bring Near\",\n            \"primary\": false,\n            \"accepted_answer\": true\n         }\n      &#93;,\n      \"auxiliary_meanings\": &#91;\n         {\n            \"meaning\": \"To get near\",\n            \"type\": \"whitelist\"\n         }\n      &#93;,\n      \"readings\": &#91;\n         {\n            \"reading\": \"\u3061\u304b\u3065\u304f\",\n            \"primary\": true,\n            \"accepted_answer\": true\n         }\n      &#93;,\n      \"parts_of_speech\": &#91;\n      &#93;,\n      \"component_subject_ids\": &#91;\n\n      &#93;,\n      \"meaning_mnemonic\": \"\",\n      \"reading_mnemonic\": \"\",\n      \"context_sentences\": &#91;\n      &#93;,\n      \"pronunciation_audios\": &#91;\n         {\n            \"url\": \"https:\/\/files.wanikani.com\/8v7c4dzigsg39t9gkkcy75bods9r\",\n            \"metadata\": {\n               \"gender\": \"female\",\n               \"source_id\": 27780,\n               \"pronunciation\": \"\u3061\u304b\u3065\u304f\",\n               \"voice_actor_id\": 1,\n               \"voice_actor_name\": \"Kyoko\",\n               \"voice_description\": \"Tokyo accent\"\n            },\n            \"content_type\": \"audio\/webm\"\n         },\n         {\n            \"url\": \"https:\/\/files.wanikani.com\/hckcnwjnyw2ridxwv6sxd9l3fxfc\",\n            \"metadata\": {\n               \"gender\": \"female\",\n               \"source_id\": 27780,\n               \"pronunciation\": \"\u3061\u304b\u3065\u304f\",\n               \"voice_actor_id\": 1,\n               \"voice_actor_name\": \"Kyoko\",\n               \"voice_description\": \"Tokyo accent\"\n            },\n            \"content_type\": \"audio\/mpeg\"\n         },\n         {\n            \"url\": \"https:\/\/files.wanikani.com\/hrc80byni6fy1sbuglr2r19djl02\",\n            \"metadata\": {\n               \"gender\": \"male\",\n               \"source_id\": 10900,\n               \"pronunciation\": \"\u3061\u304b\u3065\u304f\",\n               \"voice_actor_id\": 2,\n               \"voice_actor_name\": \"Kenichi\",\n               \"voice_description\": \"Tokyo accent\"\n            },\n            \"content_type\": \"audio\/mpeg\"\n         },\n         {\n            \"url\": \"https:\/\/files.wanikani.com\/cuhicrkl260gnf7kecat1yoxvayi\",\n            \"metadata\": {\n               \"gender\": \"male\",\n               \"source_id\": 10900,\n               \"pronunciation\": \"\u3061\u304b\u3065\u304f\",\n               \"voice_actor_id\": 2,\n               \"voice_actor_name\": \"Kenichi\",\n               \"voice_description\": \"Tokyo accent\"\n            },\n            \"content_type\": \"audio\/webm\"\n         }\n      &#93;,\n      \"lesson_position\": int,\n      \"spaced_repetition_system_id\": 1\n   }\n}<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki dark-plus\" style=\"background-color: #1E1E1E\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #D4D4D4\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #9CDCFE\">&quot;id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">3434<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #9CDCFE\">&quot;object&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;vocabulary&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #9CDCFE\">&quot;url&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/api.wanikani.com\/v2\/subjects\/3434&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #9CDCFE\">&quot;data_updated_at&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;2025-11-18T14:31:49.951360Z&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   <\/span><span style=\"color: #9CDCFE\">&quot;data&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;created_at&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;2012-07-22T23:28:45.447595Z&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;level&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">8<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;slug&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u8fd1\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;hidden_at&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">null<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;document_url&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/www.wanikani.com\/vocabulary\/%E8%BF%91%E3%81%A5%E3%81%8F&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;characters&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u8fd1\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;meanings&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;meaning&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;To Get Close&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;primary&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;accepted_answer&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;meaning&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;To Approach&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;primary&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;accepted_answer&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;meaning&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;To Draw Near&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;primary&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;accepted_answer&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;meaning&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;To Near&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;primary&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;accepted_answer&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;meaning&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;To Bring Near&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;primary&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">false<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;accepted_answer&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;auxiliary_meanings&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;meaning&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;To get near&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;whitelist&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;readings&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;reading&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u3061\u304b\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;primary&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;accepted_answer&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #569CD6\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;parts_of_speech&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;component_subject_ids&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;meaning_mnemonic&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;reading_mnemonic&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;context_sentences&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;pronunciation_audios&quot;<\/span><span style=\"color: #D4D4D4\">: &#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;url&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/files.wanikani.com\/8v7c4dzigsg39t9gkkcy75bods9r&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;metadata&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;female&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;source_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">27780<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;pronunciation&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u3061\u304b\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_name&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Kyoko&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_description&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Tokyo accent&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;content_type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;audio\/webm&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;url&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/files.wanikani.com\/hckcnwjnyw2ridxwv6sxd9l3fxfc&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;metadata&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;female&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;source_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">27780<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;pronunciation&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u3061\u304b\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">1<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_name&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Kyoko&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_description&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Tokyo accent&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;content_type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;audio\/mpeg&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;url&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/files.wanikani.com\/hrc80byni6fy1sbuglr2r19djl02&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;metadata&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;male&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;source_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">10900<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;pronunciation&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u3061\u304b\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_name&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Kenichi&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_description&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Tokyo accent&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;content_type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;audio\/mpeg&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;url&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;https:\/\/files.wanikani.com\/cuhicrkl260gnf7kecat1yoxvayi&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;metadata&quot;<\/span><span style=\"color: #D4D4D4\">: {<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;gender&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;male&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;source_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">10900<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;pronunciation&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;\u3061\u304b\u3065\u304f&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">2<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_actor_name&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Kenichi&quot;<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">               <\/span><span style=\"color: #9CDCFE\">&quot;voice_description&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;Tokyo accent&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            },<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">            <\/span><span style=\"color: #9CDCFE\">&quot;content_type&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #CE9178\">&quot;audio\/webm&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">         }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      &#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;lesson_position&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #F44747\">int<\/span><span style=\"color: #D4D4D4\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">      <\/span><span style=\"color: #9CDCFE\">&quot;spaced_repetition_system_id&quot;<\/span><span style=\"color: #D4D4D4\">: <\/span><span style=\"color: #B5CEA8\">1<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">   }<\/span><\/span>\n<span class=\"line\"><span style=\"color: #D4D4D4\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Please note that I have removed data from the above snippet that is protected intellectual property of Tofugu\/WaniKani.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Looking at the above format, WaniKani actually has two fields for definitions: meanings, and auxiliary meanings. I&#8217;m not sure what the difference is on the backend, but to grab the WaniKani definitions I just had to look up the item from the pickle and add the definitions to a simple array:<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>wanikani_definitions = []\ndata = item.get(\"data\",{})\nmeanings = [m&#91;\"meaning\"&#93; for m in data.get(\"meanings\",[]) if m&#91;\"accepted_answer\"&#93;]\nauxiliary_meanings = [m&#91;\"meaning\"&#93; for m in data.get(\"auxiliary_meanings\",[]) if m&#91;\"type\"&#93; == \"whitelist\"]\nwanikani_definitions = meanings + auxiliary_meanings<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme-darker\" style=\"background-color: #212121\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #EEFFFF\">wanikani_definitions <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">[]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">data <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> item<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">data<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,{})<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">meanings <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">[<\/span><span style=\"color: #EEFFFF\">m<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">meaning<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF; font-style: italic\">for<\/span><span style=\"color: #EEFFFF\"> m <\/span><span style=\"color: #89DDFF; font-style: italic\">in<\/span><span style=\"color: #EEFFFF\"> data<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">meanings<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,[])<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF; font-style: italic\">if<\/span><span style=\"color: #EEFFFF\"> m<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">accepted_answer<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">auxiliary_meanings <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">[<\/span><span style=\"color: #EEFFFF\">m<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">meaning<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF; font-style: italic\">for<\/span><span style=\"color: #EEFFFF\"> m <\/span><span style=\"color: #89DDFF; font-style: italic\">in<\/span><span style=\"color: #EEFFFF\"> data<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">auxiliary_meanings<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,[])<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF; font-style: italic\">if<\/span><span style=\"color: #EEFFFF\"> m<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">type<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">==<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">whitelist<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">wanikani_definitions <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> meanings <\/span><span style=\"color: #89DDFF\">+<\/span><span style=\"color: #EEFFFF\"> auxiliary_meanings<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Sweet! I hammered out some code to compare the sets of definitions and to add the needed ones to the user synonyms field in the WaniKani object and.. wait. Where the hell are user definitions stored? There&#8217;s absolutely nothing in the <code>subjects<\/code> data that describes that!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The <em>WaniKani <\/em>API Part 2: User Content<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Naturally, user created content can&#8217;t be stored at the same endpoint as the real learning text, so <em>WaniKani<\/em> uses a whole different endpoint: <code>study_materials<\/code>. Each &#8220;study material&#8221; has a field for subject_id, which ties it back to the original term, and each original term can only have one study material (per user). Creating a study material is very simple, but because each term can only be assigned once, I have to map every study material to the vocab list <em>before I do anything else<\/em>. I might as well just build my own objects from the start! Welp, time for a new workflow:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><code>get study materials from wanikani -> get vocab terms from wanikani -> map study materials to terms -> get definitions from dictionary -> compare definitions -> add delta via API<\/code><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">I kept all of the working data in one big block, and just added information to it as I went. This new workflow worked great, I just had some more peculiarities to handle. For instance, if user synonyms already exist for a term, a PUT doesn&#8217;t add on top, it only adds the new definitions. Logic is needed to add the new definitions on top and send the whole new array. Similarly, there were some otherwise unknown limits on user synonyms: each term can have a maximum of 8, and they can only be 64 characters long. Nothing too tricky, but it definitely took some trial and error to get there!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">From there, it was mostly performance improvements. The WaniKani API limits users to 60 requests per minute, but API responses include fields that tell you both how many requests you have left and how much time you have left. With these, I built a wrapper for requests to handle naturally backing off at the limit. But why make a request if you&#8217;re not updating anything in the first place? I also built logic to add an update flag to my big block of data, and only go through with an update if it&#8217;s needed.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>#check existing wanikani definitions (and user synonyms) against dictionary definitions to add more user synonyms\ndef update_definitions(index:list&#91;dict&#93;) -> list&#91;dict&#93;:\n    for entry in index:\n        #can't iterate over None, have to make it empty list instead\n        if entry.get(\"study_material_definitions\") is None:\n            entry&#91;\"study_material_definitions\"&#93; = []\n        \n        #normalize case\n        wani_defs = {w.lower() for w in entry.get(\"wanikani_definitions\",[])}\n        synonyms = {s.lower() for s in entry.get(\"study_material_definitions\",[])}\n\n        additions = [] #for tracking to see if we need to update on wanikani\n\n        #walk through dictionary defs and add if not already represented\n        for definition in entry.get(\"dictionary_definitions\",[]):\n            #API allows a max of 8 user synonyms, break the loop early if we're there\n            if len(entry&#91;\"study_material_definitions\"&#93;) >= 8:\n                break\n            \n            if definition.lower() not in wani_defs and definition.lower() not in synonyms:\n                entry&#91;\"study_material_definitions\"&#93;.append(definition)\n                synonyms.add(definition.lower())\n                additions.append(definition.lower())\n    \n        entry&#91;\"update_wanikani\"&#93; = bool(additions) #create boolean flag for updating wanikani\n    return index<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme-darker\" style=\"background-color: #212121\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #545454; font-style: italic\">#check existing wanikani definitions (and user synonyms) against dictionary definitions to add more user synonyms<\/span><\/span>\n<span class=\"line\"><span style=\"color: #C792EA\">def<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #82AAFF\">update_definitions<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #EEFFFF; font-style: italic\">index<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\">list<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #FFCB6B\">dict<\/span><span style=\"color: #89DDFF\">&#93;)<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">-&gt;<\/span><span style=\"color: #EEFFFF\"> list<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #FFCB6B\">dict<\/span><span style=\"color: #89DDFF\">&#93;:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #89DDFF; font-style: italic\">for<\/span><span style=\"color: #EEFFFF\"> entry <\/span><span style=\"color: #89DDFF; font-style: italic\">in<\/span><span style=\"color: #EEFFFF\"> index<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #545454; font-style: italic\">#can&#39;t iterate over None, have to make it empty list instead<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF; font-style: italic\">if<\/span><span style=\"color: #EEFFFF\"> entry<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">study_material_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">)<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">is<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">None:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            entry<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">study_material_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">[]<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #545454; font-style: italic\">#normalize case<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        wani_defs <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">{<\/span><span style=\"color: #EEFFFF\">w<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">lower<\/span><span style=\"color: #89DDFF\">()<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF; font-style: italic\">for<\/span><span style=\"color: #EEFFFF\"> w <\/span><span style=\"color: #89DDFF; font-style: italic\">in<\/span><span style=\"color: #EEFFFF\"> entry<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">wanikani_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,[])}<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        synonyms <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">{<\/span><span style=\"color: #EEFFFF\">s<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">lower<\/span><span style=\"color: #89DDFF\">()<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF; font-style: italic\">for<\/span><span style=\"color: #EEFFFF\"> s <\/span><span style=\"color: #89DDFF; font-style: italic\">in<\/span><span style=\"color: #EEFFFF\"> entry<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">study_material_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,[])}<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        additions <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">[]<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #545454; font-style: italic\">#for tracking to see if we need to update on wanikani<\/span><\/span>\n<span class=\"line\"><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #545454; font-style: italic\">#walk through dictionary defs and add if not already represented<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF; font-style: italic\">for<\/span><span style=\"color: #EEFFFF\"> definition <\/span><span style=\"color: #89DDFF; font-style: italic\">in<\/span><span style=\"color: #EEFFFF\"> entry<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">get<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">dictionary_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,[]):<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #545454; font-style: italic\">#API allows a max of 8 user synonyms, break the loop early if we&#39;re there<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF; font-style: italic\">if<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #82AAFF\">len<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #82AAFF\">entry<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">study_material_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;)<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&gt;=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F78C6C\">8<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">                <\/span><span style=\"color: #89DDFF; font-style: italic\">break<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF; font-style: italic\">if<\/span><span style=\"color: #EEFFFF\"> definition<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">lower<\/span><span style=\"color: #89DDFF\">()<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">not<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">in<\/span><span style=\"color: #EEFFFF\"> wani_defs <\/span><span style=\"color: #89DDFF\">and<\/span><span style=\"color: #EEFFFF\"> definition<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">lower<\/span><span style=\"color: #89DDFF\">()<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">not<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">in<\/span><span style=\"color: #EEFFFF\"> synonyms<\/span><span style=\"color: #89DDFF\">:<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">                entry<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">study_material_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;.<\/span><span style=\"color: #82AAFF\">append<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #82AAFF\">definition<\/span><span style=\"color: #89DDFF\">)<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">                synonyms<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">add<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #82AAFF\">definition<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">lower<\/span><span style=\"color: #89DDFF\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">                additions<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">append<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #82AAFF\">definition<\/span><span style=\"color: #89DDFF\">.<\/span><span style=\"color: #82AAFF\">lower<\/span><span style=\"color: #89DDFF\">())<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        entry<\/span><span style=\"color: #89DDFF\">&#91;<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">update_wanikani<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">&#93;<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">=<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #FFCB6B\">bool<\/span><span style=\"color: #89DDFF\">(<\/span><span style=\"color: #82AAFF\">additions<\/span><span style=\"color: #89DDFF\">)<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #545454; font-style: italic\">#create boolean flag for updating wanikani<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #89DDFF; font-style: italic\">return<\/span><span style=\"color: #EEFFFF\"> index<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">The End Product<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">At this point, I was pretty proud of it, and decided I wanted to post about it at the very least, so I added several usability improvements. I turned it into an interactive script that asks which levels of vocab you want to focus on (and removed the pickle index because the smaller size makes it a waste), added error handling for missing environment variables, helpful output as the script runs, and a prompt for the user to review sample output before making the changes on WaniKani.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Below is an excerpt from the final output, before being pushed to WaniKani. <code>wani_kani_definitions<\/code> and <code>dictionary_definitions<\/code> are from the lookups, and <code>study_material_definitions<\/code> should be the delta of those two (plus whatever was custom made by the user). <code>id<\/code> and <code>term<\/code> are self explanatory, while <code>update_wanikani<\/code> is the boolean mentioned above to determine whether or not a push to WaniKani has to be made.<\/p>\n\n\n\n<div class=\"wp-block-kevinbatdorf-code-block-pro\" data-code-block-pro-font-family=\"Code-Pro-JetBrains-Mono\" style=\"font-size:.875rem;font-family:Code-Pro-JetBrains-Mono,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;line-height:1.25rem;--cbp-tab-width:2;tab-size:var(--cbp-tab-width, 2)\"><span role=\"button\" tabindex=\"0\" style=\"color:#EEFFFF;display:none\" aria-label=\"Copy\" class=\"code-block-pro-copy-button\"><pre class=\"code-block-pro-copy-button-pre\" aria-hidden=\"true\"><textarea class=\"code-block-pro-copy-button-textarea\" tabindex=\"-1\" aria-hidden=\"true\" readonly>{\n        \"id\": 4122,\n        \"term\": \"\u7948\u308b\",\n        \"study_material_id\": null,\n        \"study_material_definitions\": &#91;\n            \"to say a prayer\",\n            \"to say grace\",\n            \"to hope\"\n        &#93;,\n        \"wanikani_definitions\": &#91;\n            \"To Pray For\",\n            \"To Pray\",\n            \"To Pray For Something\",\n            \"To Wish\",\n            \"To Wish Something\",\n            \"To Pray That\"\n        &#93;,\n        \"dictionary_definitions\": &#91;\n            \"to pray\",\n            \"to say a prayer\",\n            \"to say grace\",\n            \"to wish\",\n            \"to hope\"\n        &#93;,\n        \"update_wanikani\": true\n    }<\/textarea><\/pre><svg xmlns=\"http:\/\/www.w3.org\/2000\/svg\" style=\"width:24px;height:24px\" fill=\"none\" viewBox=\"0 0 24 24\" stroke=\"currentColor\" stroke-width=\"2\"><path class=\"with-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4\"><\/path><path class=\"without-check\" stroke-linecap=\"round\" stroke-linejoin=\"round\" d=\"M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2\"><\/path><\/svg><\/span><pre class=\"shiki material-theme-darker\" style=\"background-color: #212121\" tabindex=\"0\"><code><span class=\"line\"><span style=\"color: #89DDFF\">{<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C792EA\">id<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #F78C6C\">4122<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C792EA\">term<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">\u7948\u308b<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C792EA\">study_material_id<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">null,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C792EA\">study_material_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to say a prayer<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to say grace<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to hope<\/span><span style=\"color: #89DDFF\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C792EA\">wanikani_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">To Pray For<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">To Pray<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">To Pray For Something<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">To Wish<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">To Wish Something<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">To Pray That<\/span><span style=\"color: #89DDFF\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C792EA\">dictionary_definitions<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">&#91;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to pray<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to say a prayer<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to say grace<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to wish<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">            <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C3E88D\">to hope<\/span><span style=\"color: #89DDFF\">&quot;<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&#93;,<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">        <\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #C792EA\">update_wanikani<\/span><span style=\"color: #89DDFF\">&quot;<\/span><span style=\"color: #89DDFF\">:<\/span><span style=\"color: #EEFFFF\"> <\/span><span style=\"color: #89DDFF\">true<\/span><\/span>\n<span class=\"line\"><span style=\"color: #EEFFFF\">    <\/span><span style=\"color: #89DDFF\">}<\/span><\/span><\/code><\/pre><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"454\" height=\"184\" src=\"http:\/\/18.191.103.99\/wp-content\/uploads\/2026\/01\/image-2.png\" alt=\"\" class=\"wp-image-178\" srcset=\"https:\/\/learnwithpatrick.casa\/wp-content\/uploads\/2026\/01\/image-2.png 454w, https:\/\/learnwithpatrick.casa\/wp-content\/uploads\/2026\/01\/image-2-300x122.png 300w\" sizes=\"auto, (max-width: 454px) 100vw, 454px\" \/><figcaption class=\"wp-element-caption\">Sample console output for level 20 vocabulary<\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Will it stop me from getting things wrong? Nope! It&#8217;s barely helped at all! But it does allow me to see even more definitions for terms, which is pretty sweet. Especially the more colloquial ones! I&#8217;m glad I undertook the project, even if it forced me to reckon with the fact that I know less Japanese than I wish I did. Only one way to fix that! I&#8217;ve since come to realize that getting things wrong on WaniKani is ok, it just reinforces the knowledge that much better. It truly is a feature of the spaced repetition system.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The completed script is available on my <a href=\"https:\/\/github.com\/pmalley130\/wanikani-synonyms\">GitHub<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This will likely be my last post for a while, since I start my Master&#8217;s program in about a week! I&#8217;ll be sure to write about that when I finish, if not sometime during the program.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Sometimes a short project hits you like a bolt of divine inspiration, and sometimes it hits you because you&#8217;re frustrated at your own failings and think there must be a programmatic fix for them. I started this as the latter, but I&#8217;ve since found peace with my failings since this didn&#8217;t really help it at [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-container-style":"default","site-container-layout":"default","site-sidebar-layout":"default","disable-article-header":"default","disable-site-header":"default","disable-site-footer":"default","disable-content-area-spacing":"default","footnotes":""},"categories":[2],"tags":[7,8,18],"class_list":["post-170","post","type-post","status-publish","format-standard","hentry","category-projects","tag-api","tag-automation","tag-python"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=\/wp\/v2\/posts\/170","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=170"}],"version-history":[{"count":0,"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=\/wp\/v2\/posts\/170\/revisions"}],"wp:attachment":[{"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=170"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=170"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/learnwithpatrick.casa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=170"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}