Files
kjv_api/README.txt
T
2026-10-26 20:30:43 -07:00

221 lines
11 KiB
Plaintext

KJV-API
=======
King James Version web API is a machine and human callable service to
query the King James Bible and provides useful features, such as random
verses and a quote of the day.
It is a single dependancyless program (kjv-api) and its companion sqlite3
database (kjv.db). Those two files are the entire distribution.
EXTERNAL DATA
=============
The software uses a sqlite3 database as external data dependancy, saved locally
and modified to remove false Bible translations (included)
https://github.com/scrollmapper/bible_databases
kjv.db also holds everything else the program serves, so there is nothing else
to copy next to it: the pages, scripts and styles (the assets table), the 1828
Webster dictionary, the spellchecking word list, users' reading plans and
shortcodes, and the logs.
INSTALLATION
============
Nothing needs to be installed to run it: no runtime, no packages, no root.
There are two ways to run it, pick one. Both start from the dist folder:
kjv-api - the program
kjv.db - its database
kjv-api.service - systemd user service, for way 2
kjv-api.nginx.conf - nginx reverse proxy site, for way 2
kjv-api.apache.conf - the same for apache, if you use that instead
Get the two files in it by building them ($ make dist, see BUILDING) or from
whoever gave them to you.
1. Run it locally, just to use it or try it
-------------------------------------------
$ dist/kjv-api
Then browse to http://127.0.0.1:1611 , Ctrl-C stops it. That's all.
It uses the kjv.db next to it, which keeps your reading plans, shortcodes and logs
(make dist replaces dist/kjv.db with a fresh one). On another port, for example
when the service (way 2) already has 1611 on this machine:
$ dist/kjv-api -addr 127.0.0.1:1612
2. Install it as a persistent service behind nginx
--------------------------------------------------
It runs as a systemd user service under your own account on 127.0.0.1:1611,
and nginx forwards your domain to it. There is no root service and no special user.
a. Put the program and database in ~/kjv-api, and start the service:
$ mkdir -p ~/kjv-api ~/.config/systemd/user
$ cp dist/kjv-api dist/kjv.db ~/kjv-api/
$ cp dist/kjv-api.service ~/.config/systemd/user/
$ systemctl --user daemon-reload
$ systemctl --user enable --now kjv-api
$ sudo loginctl enable-linger $USER # keeps it running when you log out, starts it at boot
$ curl 127.0.0.1:1611/random # a Bible verse in json means it works
b. Point nginx at it (change example.com in the file to your domain first):
$ sudo cp dist/kjv-api.nginx.conf /etc/nginx/sites-available/kjv-api
$ sudo ln -s /etc/nginx/sites-available/kjv-api /etc/nginx/sites-enabled/
$ sudo nginx -t && sudo systemctl reload nginx
$ sudo certbot --nginx -d example.com # https, optional but recommended
Already have a site on that domain? Copy just the location block from the file into it.
Settings: optional, see the environment variables below. Put them in
~/kjv-api/kjv-api.env (one NAME=value per line), chmod 600 it, and
systemctl --user restart kjv-api.
Updating: replace only the program, never kjv.db (it holds your users' reading
plans and shortcodes, and your logs). From the source folder:
$ make dist
$ install -m 755 dist/kjv-api ~/kjv-api/kjv-api
$ ~/kjv-api/kjv-api import-assets -db ~/kjv-api/kjv.db assets # only if pages changed
$ systemctl --user restart kjv-api
Logs: journalctl --user -u kjv-api -f
or: ~/kjv-api/kjv-api logs -db ~/kjv-api/kjv.db -n 100
Uninstall: systemctl --user disable --now kjv-api, then delete ~/kjv-api,
~/.config/systemd/user/kjv-api.service and the nginx site.
USAGE
=====
It only ever listens on localhost (127.0.0.1:1611 unless told otherwise), it is
meant to sit behind a reverse proxy. Asking it to listen on any other address is refused.
For development, scripts/kjv-api-test.sh builds it, copies the database, and
listens on 127.0.0.1:1612
Visiting the base directory will show the user-facing documentation via web browser or cURL.
Changing a page, script, style or data file means editing it in the source tree
and loading it into the database again, then restarting the program:
$ ./kjv-api import-assets -db kjv.db assets
The logs are in the database, there is no log rotation but the program deletes
lines older than 90 days when it starts:
$ ./kjv-api logs -db kjv.db -n 100
$ sqlite3 kjv.db "select * from logs where level = 'ERROR'"
When run by systemd the same lines also go to the journal (journalctl --user -u kjv-api),
and KJV_LOG_STDERR=1 does that outside of systemd.
When testing or doing a deployment, the directory holding kjv.db must be owned by
whatever user is running the program (sqlite3 writes its journal beside the
database), otherwise reading plans, shortcodes and logs will not be saved.
Optional environment variables
- KJV_DB - path to kjv.db instead of the -db flag
- KJV_ADDR - localhost address to listen on instead of the -addr flag
- KJV_SECRET_API_KEY - the token POST /natural expects, and the bearer token the /seqreport and
/screport listings need (without it those two do not exist).
- KJV_LOG_STDERR - set to 1 to also print the log lines to stderr (automatic under systemd)
- KJV_SEMANTIC_ADDR - where the semantic search service listens, default localhost:1613
- KJV_SERMON_DB - path to the separate sermon database. Without it the sermon
endpoints answer 503.
BUILDING
========
Only the machine that compiles needs anything: go 1.26 or newer, and make (built
and tested with go 1.27.3, get it from https://go.dev/dl/ or your package manager).
The sqlite3 driver (modernc.org/sqlite) is pure Go, no C compiler needed, and go
downloads it the first time it builds.
$ make build builds bin/kjv-api
$ make dist builds dist/kjv-api and dist/kjv.db, the two files to distribute
$ make test go vet, and any tests
Optional: sqlite3 (the command line tool) for looking at the logs and database.
CONTENTS
========
.
├── cmd
│ └── kjv-api
│ └── main.go - command line: run the server, import-assets, logs
├── internal
│ └── kjv - the program, one package
│ ├── server.go - startup, localhost listener, routes
│ ├── app.go - loads the assets from the database, builds the rich page pieces and verse rendering
│ ├── pages.go - /show /find /search /define /random /votd
│ ├── refs.go - reference resolver ("1 jn 3.16", "II Kings 2:1-4", "song of songs 2")
│ ├── state.go - /seq /plan and shortcodes, saved in the database
│ ├── sermons.go - sermon database and semantic search endpoints, optional
│ ├── store.go - the kjv.db queries and the Bible held in memory
│ ├── assets.go - import-assets, putting the files in assets/ into the database
│ ├── logdb.go - logs saved in the database
│ ├── spell.go - spellchecking suggestions from the word list
│ ├── difflib.go - fuzzy book name matching
│ └── mt.go - the random number generator that picks the verse of the day
├── db
│ └── kjv.db - KJV sqlite3 database, the start of the companion database
├── assets - everything that gets loaded into kjv.db by import-assets
│ ├── data
│ │ ├── 1828_Webster_KJV.json - Dictionary
│ │ ├── kjv.aff - KJV Spellchecking Description file
│ │ ├── kjv.dic - KJV Spellchecking dictionary file
│ │ └── *.json - book descriptions, chapter summaries, search synonyms and variants
│ ├── html
│ │ ├── dictionary.html - dictionary search landing page /define
│ │ ├── find.html - unified search bar landing page /find
│ │ ├── navbar.html - navigation bar added programatically to rich results
│ │ ├── chapter_nav.html - previous/next chapter bar
│ │ ├── heaven.html - Bible way to heaven, static page /salvation
│ │ ├── on_reading_bible.html - Introduction on good reading practices
│ │ ├── index.html - / landing page with unified search bar, the program fills in the book lists
│ │ ├── plan.html - Bible reading plan setup /plan
│ │ ├── saved.html - favorites, definitions and cross references kept in the browser /saved
│ │ ├── response.html - Template for rich verse responses
│ │ ├── search.html - Bible keyword search landing page /search
│ │ ├── search_bar.html - Unused
│ │ ├── show.html - Bible verse search landing page /show
│ │ ├── seq.html - Bible sequential verse landing page /seq
│ │ └── votd.html - Matty's test VOTD rich landing page
│ ├── js
│ │ ├── collapsible.js - js for the definition drop-down menu used in unified search
│ │ └── book_suggest.js, shortcode.js, verse_menu.js
│ ├── static
│ │ └── favicon.svg, favicon.ico
│ ├── styles
│ │ ├── collapsible.css
│ │ ├── header.css
│ │ ├── fonts
│ │ │ ├── Arizonia-Regular.ttf
│ │ │ └── Parisienne-Regular.ttf
│ │ ├── human_readable.css
│ │ ├── search_rich.css
│ │ └── votd.css
│ └── kjv_fe.html - /fe frontend page
├── dist - what gets deployed, see INSTALLATION
│ ├── kjv-api, kjv.db - built by make dist (not kept in git)
│ ├── kjv-api.service - systemd user service, port 1611
│ ├── kjv-api.nginx.conf - nginx reverse proxy site
│ └── kjv-api.apache.conf - apache reverse proxy site
├── scripts
│ ├── kjv-api.sh - builds if needed and runs the program on localhost port 1611
│ └── kjv-api-test.sh - builds and runs the program on a copy of the database on port 1612
├── tools
│ ├── av1611_dictionary_scraper.py - builds a dictionary json for the 1828 dictionary
│ ├── sanity_check.py - Endpoint testing, run alone against a running instance (needs python3-requests)
│ └── search_keywords.txt - endpoint testing queries
├── doc
│ ├── openapi.yaml
│ └── notes.txt
├── Makefile - make, make dist, make test
├── go.mod, go.sum
└── README.txt - This document
AUTHOR
======
Copyright Tyler R Dinsmoor & Matty Sneederson 2022-2026
Reimplemented in Go by demon machine claude.
SECURITY
========
- Listens on localhost only, and refuses any other address.
- The user service runs as your account, so it can read and write whatever you can. For more
separation, make an account just for it (sudo useradd -m kjv; sudo loginctl enable-linger kjv)
and do step 2a logged in as that account.
- Reading plan ids and shortcodes are random but they are the only secret; anyone holding a plan id can
move that plan. Making new ones is rate limited per visitor (by the X-Real-IP the proxy sends,
the nginx and apache files do). Plans unused for 90 days are deleted.
- Please report anything you find to the author.