Skip to content

Commit 718e45f

Browse files
roed314claude
andcommitted
Make the LMFDB pip installable
- Add pyproject.toml (setuptools) with metadata, dependencies, package data (templates, static files, yaml) and entry points: after `sage -pip install -e .` (which is what requirements.txt now does), `import lmfdb` works without PYTHONPATH manipulation and the website can be started from anywhere with `lmfdb` or `sage -python -m lmfdb`. The version number is single-sourced in lmfdb/version.py. Since psycodict is not yet released on PyPI, it is installed from its git repository; that must change before the lmfdb can be released on PyPI. - Importing lmfdb no longer connects to postgres: lmfdb.db is now a lazy proxy that connects on first use (or explicitly via db.connect()), so `import lmfdb` is cheap and has no side effects (no config.ini, flasklog, slow_queries.log or secret_key created). - Move the configuration code to lmfdb/config.py so that using the database does not pull in lmfdb.utils (and thus flask and sage); lmfdb/utils/config.py remains as a backwards-compatible shim, still runnable as a script as the CI does. When running from a git checkout everything is located as before (config.ini and secret_key at the root); when installed as a package they live in ~/.lmfdb (overridable via LMFDB_HOME/LMFDB_CONFIG or --config-file), with a config.ini in the current directory taking precedence. - Log files no longer pollute the current directory: flasklog, slow_queries.log and verification logs now default to logs/ under the checkout root (or ~/.lmfdb/logs when installed). Existing config files with the old default values are redirected transparently; explicitly configured paths are respected. - Move CONTRIBUTORS.yaml into the lmfdb package so the acknowledgments page works when installed, and run the knowl code-reference git greps in the checkout root rather than the process working directory (they now degrade gracefully when lmfdb is not run from a checkout). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 5ef81bd commit 718e45f

20 files changed

Lines changed: 829 additions & 448 deletions

.github/copilot-instructions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ pyflakes start-lmfdb.py user-manager.py lmfdb/
169169
- **40+ test files** across the codebase
170170
- **71,000+ lines** of Python code
171171
- **Complex mathematical application** with deep domain expertise required
172-
- **Large contributor base** (see CONTRIBUTORS.yaml)
172+
- **Large contributor base** (see lmfdb/CONTRIBUTORS.yaml)
173173

174174
## Working Effectively
175175

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ config.ini
1414

1515
flasklog
1616
slow_queries.log
17+
/logs/
18+
19+
# Packaging artifacts
20+
*.egg-info/
21+
build/
22+
dist/
1723

1824
# Testing files
1925
htmlcov

GettingStarted.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ Installation
5757
sage -pip install -r requirements.txt
5858
```
5959

60+
This installs the LMFDB itself (in editable mode, i.e. pointing at your
61+
checkout) together with its dependencies, so that `import lmfdb` works
62+
from `sage` regardless of the current directory; there is no need to add
63+
the checkout to your `PYTHONPATH`. Equivalently, you can run
64+
`sage -pip install -e .` (add `[dev]` to also get the testing tools).
65+
Importing `lmfdb` does not connect to the database; the connection is
66+
established the first time `lmfdb.db` is used, or explicitly via
67+
`db.connect()`.
68+
6069
### Troubleshooting with packages.
6170

6271
- If you have not run the site for a while you might get an error
@@ -129,6 +138,10 @@ Running
129138
sage -python start-lmfdb.py --debug
130139
```
131140
141+
Since the LMFDB is installed by the step above, you can equivalently run
142+
`lmfdb --debug` (a script installed by pip) or
143+
`sage -python -m lmfdb --debug`, from any directory.
144+
132145
* The effect of the (optional) --debug is that you will be running
133146
with the beta flag switched on as at dev.lmfdb.org, and also that
134147
if code fails your browser will show useful debugging information.
@@ -163,6 +176,17 @@ Running
163176
on using a different database instance, you can do so by changing
164177
config.ini in the root of the lmfdb directory.
165178
179+
* Locations of configuration and log files: when running from a git
180+
checkout, the configuration file is `config.ini` at the root of the
181+
checkout (as it always was) and log files (`flasklog`,
182+
`slow_queries.log`, verification logs) go to the `logs/` subdirectory.
183+
When the LMFDB is installed as a package rather than run from a checkout,
184+
these files live in `~/.lmfdb` instead (unless there is a `config.ini` in
185+
the current directory). The environment variables `LMFDB_HOME` (the
186+
directory for all of these files) and `LMFDB_CONFIG` (the path of the
187+
configuration file) override these defaults, as does the `--config-file`
188+
command-line option.
189+
166190
167191
CoCalc
168192
======

MANIFEST.in

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Non-python files that ship with the lmfdb package (templates, static
2+
# assets, yaml data, code snippet test fixtures); together with
3+
# `include-package-data = true` in pyproject.toml this also determines
4+
# which data files are installed
5+
recursive-include lmfdb *.yaml *.html *.css *.js *.png *.jpg *.gif *.svg *.svgz *.ico *.txt *.md *.rst *.log *.sage
6+
include lmfdb/number_fields/Database-info
7+
include lmfdb/galois_groups/Database-info
8+
global-exclude *.pyc
9+
global-exclude __pycache__

README.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@ Wiki
1414
Development
1515
-----------
1616

17-
* [Getting Started](https://github.com/LMFDB/lmfdb/blob/main/GettingStarted.md) -- cheat sheet for setting up lmfdb
17+
* [Getting Started](https://github.com/LMFDB/lmfdb/blob/main/GettingStarted.md) -- cheat sheet for setting up lmfdb.
18+
The LMFDB is pip installable: `sage -pip install -e .` from a checkout
19+
(this is what `sage -pip install -r requirements.txt` does), after which
20+
`import lmfdb` works from `sage` anywhere and the website can be started
21+
with `lmfdb` or `sage -python -m lmfdb`.
1822
* [Development Guide](https://github.com/LMFDB/lmfdb/blob/main/Development.md) -- organizing development
1923
* [Style Guide](https://github.com/LMFDB/lmfdb/blob/main/StyleGuide.md) -- how things on LMFDB pages should be styled to give the web site a coherent look
2024
* [Command-line search](https://github.com/LMFDB/lmfdb/blob/main/CommandLineSearch.md) -- searching the LMFDB from the command line with `lmfdb_search`

lmfdb/__init__.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,30 @@
1+
"""
2+
LMFDB: the database of L-functions, modular forms, and related objects.
13
2-
# psycodict was added as a dependency on May 10, 2024; we provide a useful error message for people upgrading
3-
try:
4-
import psycodict
5-
assert psycodict
6-
except ImportError:
7-
print('Missing dependency; try running "sage -pip install -r requirements.txt" in the LMFDB home folder.')
8-
raise
4+
Importing this package is lightweight; in particular it does not connect
5+
to the database. The connection is established the first time ``lmfdb.db``
6+
is used, for example::
97
10-
from .lmfdb_database import db
11-
assert db
8+
from lmfdb import db
9+
db.ec_curvedata.lookup("11.a1")
10+
11+
or explicitly via ``db.connect()``. To run the website, use the ``lmfdb``
12+
command (or ``python -m lmfdb``, or ``start-lmfdb.py`` from a git checkout).
13+
"""
14+
15+
16+
def __getattr__(name):
17+
# Lazy attributes (PEP 562), so that `import lmfdb` stays cheap
18+
if name == "db":
19+
try:
20+
from .lmfdb_database import db
21+
except ImportError:
22+
print('Missing dependency; try running "sage -pip install -e ." in the LMFDB home folder.')
23+
raise
24+
globals()["db"] = db
25+
return db
26+
raise AttributeError("module 'lmfdb' has no attribute %r" % (name,))
27+
28+
29+
def __dir__():
30+
return sorted(set(globals()) | {"db"})

lmfdb/__main__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
"""
2+
Start the LMFDB website via ``python -m lmfdb`` (or ``sage -python -m lmfdb``).
3+
"""
4+
from lmfdb.website import main
5+
6+
if __name__ == "__main__":
7+
main()

lmfdb/app.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .utils.config import get_secret_key
1+
from .config import get_secret_key
22
import os
33
from socket import gethostname
44
import time
@@ -18,12 +18,13 @@
1818
from markupsafe import escape
1919
from sage.env import SAGE_VERSION
2020
from sage.all import cached_function
21-
# acknowledgment page, reads info from CONTRIBUTORS.yaml
21+
# acknowledgment page, reads info from lmfdb/CONTRIBUTORS.yaml
2222

2323
from .logger import critical
2424
from .homepage import load_boxes, contribs
2525

26-
LMFDB_VERSION = "LMFDB Release 1.2.1"
26+
from .version import version as _lmfdb_version
27+
LMFDB_VERSION = "LMFDB Release " + _lmfdb_version
2728

2829
############################
2930
# Main app #
@@ -575,7 +576,7 @@ def add_colors():
575576
if color not in all_color_schemes:
576577
color = None
577578
if color is None:
578-
from .utils.config import Configuration
579+
from .config import Configuration
579580
color = Configuration().get_color()
580581
return {"color": all_color_schemes[color].dict()}
581582

0 commit comments

Comments
 (0)