Side project: built a free Korean Saju (4-pillar astrology) calculator. Sharing the tech stack and a few non-obvious gotchas.
Stack
- Backend: Python 3.13, Flask
- Hosting: PythonAnywhere free tier
- Astronomy: Custom Meeus algorithm (no external library, 100s/day CPU limit)
- No database: Charts are pure functions of input
Live site
https://tarofortune.pythonanywhere.com/en
Non-obvious lessons
1. Free tier CPU is precious
PythonAnywhere free tier gives 100 CPU seconds per day. Each Saju calculation iterates a Newton-style solver for solar term timing. Without caching, ~30 chart computations would burn through the limit.
from functools import lru_cache
@lru_cache(maxsize=4096)
def solar_term_jd(year: int, term_idx: int) -> float:
# ...
Solar terms repeat for the same (year, term) pair, so caching is essentially free.
2. Korean text on Windows console is hell
Default code page on Windows is cp949. Add python -X utf8 script.py or os.environ["PYTHONIOENCODING"] = "utf-8" to avoid UnicodeEncodeError on every print of Korean characters.
3. PythonAnywhere whitelist for outbound HTTPS
Free tier blocks outgoing HTTPS except to whitelisted domains. Plan for this if your app needs to call external APIs.
4. i18n the right way
I added /en/ prefix routing rather than per-template translation logic. Cleaner separation, easier SEO with hreflang.
What's next
- Multi-language expansion (Japanese, Chinese)
- Service Worker for offline support (done)
- IndexNow integration for instant Bing/Naver indexing (done)
Open to feedback on the math or UX. Try the chart reader and let me know what's off.
Top comments (0)