Skip to content

Commit

Permalink
Merge pull request #4 from edx/generate-anki-cards
Browse files Browse the repository at this point in the history
Feat: Generate anki cards from openai response
  • Loading branch information
ashultz0 authored Oct 25, 2023
2 parents f591aaf + f7434a5 commit 7232f1a
Show file tree
Hide file tree
Showing 11 changed files with 320 additions and 201 deletions.
27 changes: 27 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,33 @@ The service leverages the Anki project for flashcard management and display.
Getting Started
***************

Running The Application using Docker
====================================

.. code-block::
# Build the docker image:
make docker_build
# Spin up the containers:
make dev.up
# Enter the shell:
make app-shell
python manage.py shell
# Import function and test it:
from flashcards.apps.cards.anki import main
Start fetching content locally
==============================
checkout https://github.com/edx/ai-aside/tree/ashultz0/extractor into src
provision a user in the devstack folder with the lms running: ./provision-ida-user.sh flashcards flashcards 3000
run make install-local in ai-aside
restart lms so that the aside actually loads
You must create an XBlockAsidesConfig (admin URL: /admin/lms_xblock/xblockasidesconfig/). This model has a list of blocks you do not want asides to apply to that can be left alone, and an enabled setting that unsurprisingly should be True.


Developing
==========

Expand Down
55 changes: 55 additions & 0 deletions flashcards/apps/cards/anki.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
"""
Implementation of AnkiConnect to create cards
"""
from flashcards.apps.cards.cardgen import cards_from_block_id
import genanki


def create_anki_cards(openai_data):
"""
Generates anki cards from data
"""
my_model = genanki.Model(
1607392319,
'Simple Model',
fields=[
{'name': 'Question'},
{'name': 'Answer'},
],
templates=[
{
'name': 'Card 1',
'qfmt': '{{Question}}',
'afmt': '{{FrontSide}}<hr id="answer">{{Answer}}',
},
])

my_deck = genanki.Deck(
2059400111,
'Demo Deck 1')

rows = openai_data.split('\n')
for row in rows:
question, answer = row.split(',', 1)

my_note = genanki.Note(
model=my_model,
fields=[question, answer])

my_deck.add_note(my_note)

genanki.Package(my_deck).write_to_file('demo_output.apkg')


def main():
"""
Master function that gets a response from openai and passes the result to Anki
"""
result = cards_from_block_id('course-v1:edX+DemoX+Demo_Course',
'block-v1:edX+DemoX+Demo_Course+type@vertical+block@867dddb6f55d410caaa9c1eb9c6743ec')
# TODO: Insert some kind of data validation here to make sure openai sent back something nice
result = result.replace('\t', '')
create_anki_cards(result)


main()
2 changes: 0 additions & 2 deletions flashcards/apps/cards/cardgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@

openai.api_key = OPENAI_API_KEY

# provision a user in devstack provision-ida-user.sh flashcards flashcards 3000


def get_client(oauth_base_url=settings.LMS_ROOT_URL):
"""
Expand Down
197 changes: 0 additions & 197 deletions flashcards/utils.py

This file was deleted.

24 changes: 22 additions & 2 deletions requirements/base.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ charset-normalizer==3.3.1
# aiohttp
# requests
click==8.1.7
# via edx-django-utils
# via
# edx-django-utils
# flask
coreapi==2.3.3
# via
# django-rest-swagger
Expand Down Expand Up @@ -98,6 +100,12 @@ edx-opaque-keys==2.5.1
# via edx-drf-extensions
edx-rest-api-client==5.6.1
# via -r requirements/base.in
flask==3.0.0
# via
# aqt
# flask-cors
flask-cors==4.0.0
# via aqt
frozenlist==1.4.0
# via
# aiohttp
Expand All @@ -115,7 +123,9 @@ jinja2==3.1.2
markdown==3.5
# via anki
markupsafe==2.1.3
# via jinja2
# via
# jinja2
# werkzeug
multidict==6.0.4
# via
# aiohttp
Expand Down Expand Up @@ -176,8 +186,14 @@ requests[socks]==2.31.0
# social-auth-core
requests-oauthlib==1.3.1
# via social-auth-core
rpds-py==0.10.6
# via
# jsonschema
# referencing
semantic-version==2.10.0
# via edx-drf-extensions
send2trash==1.8.2
# via aqt
simplejson==3.19.2
# via django-rest-swagger
six==1.16.0
Expand Down Expand Up @@ -210,6 +226,10 @@ uritemplate==4.1.1
# via coreapi
urllib3==2.0.7
# via requests
waitress==2.1.2
# via aqt
werkzeug==3.0.0
# via flask
yarl==1.9.2
# via aiohttp
zipp==3.17.0
Expand Down
Loading

0 comments on commit 7232f1a

Please sign in to comment.