Spaced Spatial Repetition software with AI-generated sentence variations for language learning
Project description
MorphCards
Spaced Spatial Repetition (SSR) software with AI-generated sentence variations for language learning.
🎯 Overview
Traditional SSR software often repeats the exact same sentence cards, leading users to memorize the front of cards rather than truly learning the language. MorphCards solves this by generating new, contextually appropriate sentences each time a card is reviewed, ensuring learners can identify and understand words in different contexts.
📚 Documentation
- Architecture Documentation - System design, data flow, and component diagrams
- API Reference - Detailed class and method documentation
- Examples - Usage examples and tutorials
🔑 Environment Variables
This documentation assumes Gemini is being used by default. All examples assume you have a .env file with your API keys.
Create a .env file in your project root:
# .env file
GEMINI_API_KEY=your-gemini-api-key-here
GEMINI_MODEL_NAME=gemini-2.5-flash # Example: gemini-2.5-flash, gemini-1.5-pro, gemini-1.5-flash
OPENAI_API_KEY=your-openai-api-key-here # Uncomment for OpenAI
OPENAI_MODEL_NAME=gpt-3.5-turbo # Example: gpt-4, gpt-3.5-turbo
For OpenAI users: Replace GEMINI_API_KEY with OPENAI_API_KEY in your .env file.
✨ Features
- FSRS-based Spaced Repetition: Uses the Free Spaced Repetition Scheduler for optimal learning intervals
- AI-Generated Sentence Variations: Creates new sentences using OpenAI or Google Gemini APIs
- Vocabulary-Aware Generation: Ensures new sentences only use previously learned vocabulary
- In-Memory Database: Fast DuckDB-based storage for cards and review history
- Parameter Optimization: Automatically optimizes FSRS parameters based on your learning patterns
- Multiple AI Services: Support for both OpenAI and Google Gemini APIs
- CLI Interface: Command-line tool for daily use
- Web Demo: Interactive Gradio interface for testing and demonstration
🚀 Quick Start
Installation
# Install from PyPI
pip install morphcards
# Install with demo dependencies
pip install morphcards[demo]
# Install with development dependencies
pip install morphcards[dev]
🎯 Quick Demo (One Command)
# Run demo immediately with Podman
podman run --rm -p 7860:7860 \
--env-file .env \
docker.io/library/python:3.11-slim \
bash -c "pip install morphcards[demo] && python -m morphcards.demo"
Then open http://localhost:7860 in your browser!
Note: The first run may take a few minutes as it downloads and installs dependencies.
Environment Variables: This documentation assumes Gemini is being used. For OpenAI users, replace GEMINI_API_KEY with OPENAI_API_KEY in all commands.
Pro Tip: Use make all to run everything at once! See the Makefile section for details.
Container Setup (Recommended)
# Using Podman (recommended)
podman build -t morphcards .
podman run -p 7860:7860 morphcards
# One-shot demo with Podman (no build required)
podman run --rm -p 7860:7860 --env-file .env docker.io/library/python:3.11-slim bash -c "
pip install morphcards[demo] &&
python -m morphcards.demo
"
# Using Docker
docker build -t morphcards .
docker run -p 7860:7860 morphcards
Basic Usage
from morphcards import Card, Scheduler, VocabularyDatabase
from morphcards.ai import AIServiceFactory
from datetime import datetime
# Initialize components
db = VocabularyDatabase()
scheduler = Scheduler()
ai_service = AIServiceFactory.create_service("openai", model_name="gpt-3.5-turbo") # Example with model_name
# Create a card
card = Card(
id="hello_1",
word="hello",
sentence="Hello, how are you?",
original_sentence="Hello, how are you?",
due_date=datetime.now()
)
# Add to database
db.add_card(card)
# Review the card
updated_card, review_log = scheduler.review_card(
card=card,
rating=3, # Good
now=datetime.now(),
ai_api_key="your-api-key",
vocabulary_database=db,
ai_service=ai_service
)
print(f"New sentence: {updated_card.sentence}")
Command Line Interface
# Add a new card
morphcards add "bonjour" "Bonjour, comment allez-vous?" --language French
# Review due cards (uses .env file)
morphcards review --ai-service gemini --model-name gemini-2.5-flash
# Show statistics
morphcards stats
# Optimize parameters
morphcards optimize
🏗️ Architecture
For detailed architecture diagrams and system design, see Architecture Documentation.
Core Components
Card: Represents a flashcard with word, sentence, and FSRS parametersScheduler: Manages spaced repetition scheduling using FSRS algorithmOptimizer: Optimizes FSRS parameters based on review historyVocabularyDatabase: Stores cards, reviews, and vocabulary using DuckDBAIService: Abstract interface for AI sentence generationOpenAIService: OpenAI API integrationGeminiService: Google Gemini API integration
Data Flow
- Card Creation: User creates a card with word and sentence
- Review Process: User reviews card and rates their recall
- AI Generation: System generates new sentence using learned vocabulary
- FSRS Update: Card parameters updated based on rating
- Database Storage: Updated card and review log saved
🔧 Configuration
Environment Variables
# Google Gemini API (recommended)
export GEMINI_API_KEY="your-gemini-key"
export GEMINI_MODEL_NAME="gemini-2.5-flash" # Example: gemini-2.5-flash, gemini-1.5-pro, gemini-1.5-flash
# OpenAI API (alternative)
export OPENAI_API_KEY="your-openai-key"
export OPENAI_MODEL_NAME="gpt-3.5-turbo" # Example: gpt-4, gpt-3.5-turbo
API Service Selection
# Choose AI service (Gemini recommended)
ai_service = AIServiceFactory.create_service("gemini", model_name="gemini-2.5-flash")
# Choose AI service (OpenAI alternative)
ai_service = AIServiceFactory.create_service("openai", model_name="gpt-4")
🐳 Containerization
Using Podman (Recommended)
# Build and run with Podman
podman build -t morphcards .
podman run -p 7860:7860 --env-file .env morphcards
# Using Podman Compose (uses .env file)
podman-compose up -d
Using Docker (Alternative)
# Build and run with Docker
docker build -t morphcards .
docker run -p 7860:7860 --env-file .env morphcards
# Using Docker Compose (uses .env file)
docker-compose up -d
🚀 Quick Start with Makefile
# Run everything at once (recommended)
make all
# Or use individual commands
make build # Build container
make demo # Run demo in container (one-shot)
make demo-local # Run demo locally (requires install)
make demo-quick # Quick local demo (auto-install)
make run # Build and run
make clean # Clean up
make help # Show all commands
Note: The Makefile assumes podman is being used. For docker users, replace podman with docker in the Makefile or use the container commands directly.
Local Development: For development and testing, use make demo-quick which installs dependencies locally and runs the demo without containers.
Note: If you encounter pip version issues, the container-based demo (make demo) is recommended as it uses a fresh Python environment.
🧪 Testing
# Run all tests
pytest
# Run with coverage
pytest --cov=morphcards
# Run specific test categories
pytest -m unit
pytest -m integration
📊 Demo Interface
Start the interactive demo:
# Run demo locally
python -m morphcards.demo
# Or use the CLI
morphcards demo
🐳 Quick Demo with Podman (One-shot)
# Run demo directly with Podman (no build required)
podman run --rm -p 7860:7860 \
--env-file .env \
docker.io/library/python:3.11-slim \
bash -c "pip install morphcards[demo] && python -m morphcards.demo"
# Alternative: Run with specific version
podman run --rm -p 7860:7860 \
--env-file .env \
docker.io/library/python:3.11-slim \
bash -c "pip install 'morphcards[demo]>=0.1.0' && python -m morphcards.demo"
🚀 Demo Features
The demo provides:
- Add Cards: Create new learning cards
- Review Cards: Interactive review process with AI sentence generation
- Statistics: View learning progress and vocabulary stats
- Optimization: Optimize FSRS parameters
🔍 API Reference
Core Classes
Card
id: Unique identifierword: Word to learnsentence: Current sentenceoriginal_sentence: Original sentence when createdstability: FSRS stability parameter (nullable)difficulty: FSRS difficulty parameter (nullable)due_date: Next review datestate: FSRS state (New, Learning, Review, Relearning)
Scheduler
review_card(): Process card review and generate new sentence_fsrs: Internal FSRS scheduler instance (manages parameters internally)
VocabularyDatabase
add_card(): Add new cardget_due_cards(): Get cards ready for reviewget_learned_vocabulary(): Get all learned wordsadd_review_log(): Record review completion (now stores UUID for review logs)stabilityanddifficultyin cards table are now nullable.
🤝 Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for new functionality
- Run the test suite
- Submit a pull request
Development Setup
# Clone repository
git clone https://github.com/felipepenha/morphcards.git
cd morphcards
# Install development dependencies
pip install -e .[dev]
# Install pre-commit hooks
pre-commit install
# Run linting
black src/ tests/
mypy src/
ruff check src/ tests/
# Run with Podman (recommended)
podman build -t morphcards-dev .
podman run -it --rm -p 7860:7860 --env-file .env morphcards-dev
# Or with Docker
docker build -t morphcards-dev .
docker run -it --rm -p 7860:7860 --env-file .env morphcards-dev
📝 License
This project is licensed under the MIT License - see the LICENSE file for details.
🙏 Acknowledgments
- FSRS - Free Spaced Repetition Scheduler
- DuckDB - In-process analytical database
- OpenAI - AI language models
- Google Gemini - AI language models
📞 Support
- Author: Felipe Campos Penha
- Email: felipe.penha@alumni.usp.br
- GitHub: @felipepenha
- Issues: GitHub Issues
🔧 Troubleshooting
Demo Issues
Demo won't start: Make sure port 7860 is available. Use a different port with -p 8080:7860 if needed.
API key errors: Ensure your .env file contains the correct API key. For Gemini users: GEMINI_API_KEY=your-key. For OpenAI users: OPENAI_API_KEY=your-key.
Slow first run: The one-shot demo downloads dependencies on first run. Subsequent runs will be faster.
Permission denied: On some systems, you may need to run podman with sudo or configure user namespaces.
Common Commands
# Check if port is in use
lsof -i :7860
# Kill process using port
kill -9 $(lsof -t -i:7860)
# Run on different port
podman run --rm -p 8080:7860 --env-file .env \
docker.io/library/python:3.11-slim \
bash -c "pip install morphcards[demo] && python -m morphcards.demo"
# Note: Your .env file should contain either GEMINI_API_KEY or OPENAI_API_KEY
MorphCards - Making language learning more effective through intelligent spaced repetition.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file morphcards-0.1.0.tar.gz.
File metadata
- Download URL: morphcards-0.1.0.tar.gz
- Upload date:
- Size: 40.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cc6244c8307b13bf201d2ca0e28771f36a742638503fba6c7073f7323ecd8ca
|
|
| MD5 |
41b7fdcbf7351bebe2b6fbad8cc097d8
|
|
| BLAKE2b-256 |
87b5b39e1b4a9bb2ad125efc79bd87ba1ae9f768da056023181790dded96f00e
|
Provenance
The following attestation bundles were made for morphcards-0.1.0.tar.gz:
Publisher:
publish-to-pypi.yml on felipepenha/morphcards
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
morphcards-0.1.0.tar.gz -
Subject digest:
6cc6244c8307b13bf201d2ca0e28771f36a742638503fba6c7073f7323ecd8ca - Sigstore transparency entry: 451313590
- Sigstore integration time:
-
Permalink:
felipepenha/morphcards@7536d85ab9ee45cf71b84c4386ca0453910e84ee -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/felipepenha
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@7536d85ab9ee45cf71b84c4386ca0453910e84ee -
Trigger Event:
release
-
Statement type:
File details
Details for the file morphcards-0.1.0-py3-none-any.whl.
File metadata
- Download URL: morphcards-0.1.0-py3-none-any.whl
- Upload date:
- Size: 28.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2f11a18a8a97ce1f5961a3a133cd190801cda33fc22623768913caae18b384c
|
|
| MD5 |
2681291a5fdded10cf1067daa7937967
|
|
| BLAKE2b-256 |
5c5bc4b5801599369d2f3fdd54a7f46e1326733e025dd25a9923a8b996a0577f
|
Provenance
The following attestation bundles were made for morphcards-0.1.0-py3-none-any.whl:
Publisher:
publish-to-pypi.yml on felipepenha/morphcards
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
morphcards-0.1.0-py3-none-any.whl -
Subject digest:
e2f11a18a8a97ce1f5961a3a133cd190801cda33fc22623768913caae18b384c - Sigstore transparency entry: 451313607
- Sigstore integration time:
-
Permalink:
felipepenha/morphcards@7536d85ab9ee45cf71b84c4386ca0453910e84ee -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/felipepenha
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-to-pypi.yml@7536d85ab9ee45cf71b84c4386ca0453910e84ee -
Trigger Event:
release
-
Statement type: