| tests | ||
| the_works | ||
| utils | ||
| .flaskenv | ||
| .gitignore | ||
| README.md | ||
| requirements.txt | ||
| tmp.md | ||
| tmp.py | ||
the_works – a publication management tool for writers
This software project
- supports managing texts and publications with multiple languages, pseudonyms, genres, publishers, series, editions, and more
- supports storage of cover images
- focuses on ease-of-use, safety, and speed
- written and field-tested by an actual writer
the_works also is
- based on common technologies like Python, SQL, and HTML/JavaScript
- underlying frameworks are Flask and SQLAlchemy
- includes test coverage (using pytest)
Setup
$ git clone https://git.unterdemradar.de/tobias/the_works.git
$ cd the_works
$ python -m venv .venv
$ . .venv/bin/activate
$ pip install -r requirements.txt
Configuration
From the environment
When the_works is started, the app first reads all environment variables prefixed with "FLASK_" (e.g. "FLASK_APP"). Any variables in the file .flaskenv will be added to the environment beforehand ("python-dotenv" must be installed). This can be used to determine the mode to run the app in (development, production etc.).
Note that only those environment variables get added to the_works' configuration that begin with "FLASK_". Ths is true whether they were added on the command line, defined in.flaskenv, or even added by using Python's os.environ.
From the_works/config.py
The main configuration happens inside the file the_works/config.py. All static variables defined in the class "Config" will be added as key-value-pairs to the_works' configuration dict.
In addition to "Config", the_works will then read all values from either "DevelopmentConfig", "ProductionConfig", or "TestingConfig". These classes are all subclasses of "Config". the_works determines which subclass to use by reading the Flask configuration setting "APP_MODE". If "APP_MODE" is one of either "development", "production", or "testing", the corresponding subclass will be used. If "APP_MODE" is set to a different value or not at all, "DevelopentConfig" will be used as default.
Note that if a value is defined in both "Config" and one of its subclasses, the value from the subclass will supersede the one from the base class.
Settings for the_works
The following settings are specific to the_works:
APP_MODE = development | production | testing– detemines witch configuration to use in addition to the base config; default is development
Useful Flask settings
APP = <app_name>– set this bevore running flask on the command line if you want to omit--app the_works- either
SQLALCHEMY_DATABASE_URIorSQLALCHEMY_DATABASE_URImust be set or flask-sqlalchemy will throw an error; for URI syntax see the SQLAlchemy docs - see the list of builtin configuration values in the Flask docs
Flask commands
Execute commands with python -m flask --app the_works <command>. You can omit --app by setting the environment variable "FLASK_APP" to "the_works" (see here)
Available commands:
run: Serve app (don't use for production).shell: start a shell within the app context (I can i.e. import specific table models and test ORM data structures)
Dependencies
Python Packages
Required pip packages
- flask
- python-dotenv
- flask-sqlalchemy
- Pillow
- pytest
See also requirements.txt.
CSS and Javascript resources
- any regular (not classless) stylesheet from PicoCSS for general styling
SwitchColorMode.jsfrom Yohn's fork of PicoCSS to enable color mode switching- DataTables (JS and CSS components) to enable ordering and filtering result tables
- DataTables requires jQuery, which can either be bundled with DataTables itself or installed as a separate resource
Icons
some icons from heroicons.com
Other useful stuff
Export database schema
Method 1: sqlite3 the_works.sqlite .schema > outputfile.sql
Method 2: Open DB in SQLitebrowser and use File -> Export -> Database to SQL file …
- keep original CREATE statements
- export schema only
- overwrite old schema (DROP TABLE, then CREATE TABLE)
Generate requirements.txt
I use pipreqs to generate the file requirements.txt. The package scans all source files for import statements and uses those to extract all required Pip packages. See pipreqs -h for usage info.
Outdated: Generate SQLAlchemy code from an existing database
Right now In earlier stages, the_works reflects an existing database in order to infer the underlying data models for SQLAlchemy. Of course, this only works if all the tables already exist in the database. If the_works is run with an empty database (this happens when running tests, for example), the app will create fresh tables in the database. The necessary information about the tables can be generated from an existing database with the help of sqlacodegen. Just run this command inside the project's root directory:
sqlacodegen --generator tables sqlite:///path/to/good/db.sqlite > ./the_works/tables.py
The tool sqlacodegen can also generate Python code declaring the data models directly. This would make the use of reflection obsolete. The command would be:
sqlacodegen --generator declarative sqlite:///path/to/good/db.sqlite > outputfile.py