flask-api-development
0
总安装量
1
周安装量
安装命令
npx skills add https://github.com/findinfinitelabs/chuuk --skill flask-api-development
Agent 安装分布
amp
1
cline
1
opencode
1
cursor
1
continue
1
kimi-cli
1
Skill 文档
Flask API Development
Overview
The Chuuk Dictionary backend is a single-file monolith: app.py (~4150 lines) that contains all routes, auth logic, translation pipelines, OCR helpers, and database access. There is no Blueprint split.
Application Structure
chuuk/
âââ app.py # All Flask routes and logic (~4150 lines)
âââ src/
â âââ core/jworg_lookup.py # JW.org word lookup
â âââ database/
â â âââ db_factory.py # Connection helpers (module-level functions)
â â âââ dictionary_db.py # DictionaryDB class
â âââ ocr/ocr_processor.py
â âââ translation/
â â âââ helsinki_translator_v2.py
â â âââ hybrid_translator.py
â âââ utils/nwt_epub_parser.py
âââ config/
â âââ users.json # Authorised users
â âââ bible_books.json # Bible book metadata (66 books)
âââ requirements.txt
Key Conventions
Module-level globals (not injected)
# app.py â initialised at startup (not inside routes)
dict_db = DictionaryDB() # database handle â NOT app.db
training_status = {} # background job state
training_status_lock = threading.Lock() # guards training_status mutations
helsinki_translator = None # loaded lazily via load_helsinki_translator()
CORS is disabled (flask_cors import is commented out). Add it back deliberately if needed.
Magic-link authentication (no passwords)
magic_links = {} # {token: {'email': email, 'expires': datetime}}
active_sessions = {} # {email: session_id} â enforces single active session
@app.route('/api/auth/request-magic-link', methods=['POST'])
def request_magic_link():
email = request.json.get('email', '').lower().strip()
# ... validate email against users.json, generate token, send SMTP email ...
@app.route('/auth/magic/<token>')
def magic_link_login(token):
# ... validate token, create session, redirect to frontend ...
Route return pattern
@app.route('/api/dictionary/search', methods=['GET'])
@login_required
def api_search():
try:
query = request.args.get('q', '')
results = dict_db.search_entries(query) # use dict_db, not app.db
return jsonify({'results': results})
except Exception as e:
app.logger.error(f'Search error: {e}')
return jsonify({'error': str(e)}), 500
Background training jobs
Mutate training_status only inside training_status_lock:
with training_status_lock:
training_status['state'] = 'running'
Bible data
# Loaded from config/bible_books.json â do NOT hardcode inline
BIBLE_BOOKS = _load_bible_books() # dict keyed by book name
Environment Variables
| Variable | Purpose | Default |
|---|---|---|
FLASK_SECRET_KEY |
Session signing key | random (dev) / required (prod) |
FLASK_ENV |
Environment tag | â |
COSMOS_DB_CONNECTION_STRING |
Cosmos DB URI | â |
SMTP_HOST/PORT/USER/PASSWORD |
Magic-link email | stdout fallback |
GOOGLE_VISION_API_KEY |
Cloud Vision OCR | optional |
Testing
See tests/conftest.py. Mock dict_db via patch('app.dict_db', mock_db).
Source Files
- Backend entry point:
app.py - Database layer:
src/database/dictionary_db.py - Auth logic:
app.py(magic-link sections, ~line 83â170)