diff --git a/projects/anosql/src/python/anosql/__init__.py b/projects/anosql/src/python/anosql/__init__.py
index 4faf5e4..a58ad4d 100644
--- a/projects/anosql/src/python/anosql/__init__.py
+++ b/projects/anosql/src/python/anosql/__init__.py
@@ -1,5 +1,12 @@
-from .core import from_path, from_str, SQLOperationType
-from .exceptions import SQLLoadException, SQLParseException
+from .core import (
+    from_path,
+    from_str,
+    SQLOperationType,
+)
+from .exceptions import (
+    SQLLoadException,
+    SQLParseException,
+)
 
 
 __all__ = [
diff --git a/projects/anosql/src/python/anosql/core.py b/projects/anosql/src/python/anosql/core.py
index 3eb63a8..fa83380 100644
--- a/projects/anosql/src/python/anosql/core.py
+++ b/projects/anosql/src/python/anosql/core.py
@@ -2,7 +2,10 @@ import os
 
 from .adapters.psycopg2 import PsycoPG2Adapter
 from .adapters.sqlite3 import SQLite3DriverAdapter
-from .exceptions import SQLLoadException, SQLParseException
+from .exceptions import (
+    SQLLoadException,
+    SQLParseException,
+)
 from .patterns import (
     doc_comment_pattern,
     empty_pattern,
diff --git a/projects/archiver/hash_copy.py b/projects/archiver/hash_copy.py
index b3fc281..eb59c3b 100644
--- a/projects/archiver/hash_copy.py
+++ b/projects/archiver/hash_copy.py
@@ -3,10 +3,11 @@ A tree deduplicator and archiver tool.
 """
 
 import argparse
-from pathlib import Path
 from hashlib import sha256
+from pathlib import Path
 from shutil import copy2 as copyfile
 
+
 parser = argparse.ArgumentParser()
 parser.add_argument("from_dir", type=Path)
 parser.add_argument("to_dir", type=Path)
diff --git a/projects/archiver/org_photos.py b/projects/archiver/org_photos.py
index a69cfee..001147b 100644
--- a/projects/archiver/org_photos.py
+++ b/projects/archiver/org_photos.py
@@ -17,18 +17,16 @@ Inspired by https://github.com/herval/org_photos/blob/main/org_photos.rb
 """
 
 import argparse
-import sys
-from pathlib import Path
-from hashlib import sha256, sha512
-from datetime import date
 from datetime import datetime
-from shutil import copy2 as copyfile
+from hashlib import sha256, sha512
+from pathlib import Path
 import re
+from shutil import copy2 as copyfile
+import sys
 import typing as t
 
 # FIXME: use piexif, which supports writeback not exifread.
 import exifread
-from exifread.classes import IfdTag
 
 
 parser = argparse.ArgumentParser()
@@ -36,7 +34,7 @@ parser.add_argument("src_dir", type=Path)
 parser.add_argument("dest_dir", type=Path)
 
 
-MODIFIED_ISO_DATE = '%Y:%m:%dT%H:%M:%SF%f'
+MODIFIED_ISO_DATE = "%Y:%m:%dT%H:%M:%SF%f"
 
 
 def take(n, iter):
@@ -51,7 +49,7 @@ def take(n, iter):
 
 def exif_tags(p: Path) -> object:
     """Return the EXIF tags on an image."""
-    with open(p, 'rb') as fp:
+    with open(p, "rb") as fp:
         return exifread.process_file(fp)
 
 # EXIF tags dataset (exifread edition) -
@@ -430,7 +428,7 @@ def date_from_name(p: Path):
             # A bug
             # 2014:08:21T19:4640F1408672000
             # 2015:12:14T23:0933F1450159773
-            '%Y:%m:%dT%H:%M%SF%f',
+            "%Y:%m:%dT%H:%M%SF%f",
 
             # 2020-12-21 17.15.09.0
             "%Y-%m-%d %H.%M.%S.%f",
@@ -556,9 +554,9 @@ def img_info(p: Path) -> ImgInfo:
     camera_make = get_tag("Image Make", "Unknown")
     camera_model = get_tag("Image Model", "Unknown")
     camera_sn = get_tag("MakerNote SerialNumber", "Unknown")
-    lens_make = get_tag('EXIF LensMake', "Unknown")
-    lens_model = get_tag('EXIF LensModel', "Unknown")
-    lens_sn = get_tag('EXIF LensSerialNumber', "Unknown")
+    lens_make = get_tag("EXIF LensMake", "Unknown")
+    lens_model = get_tag("EXIF LensModel", "Unknown")
+    lens_sn = get_tag("EXIF LensSerialNumber", "Unknown")
     software = get_tag("Image Software", "Unknown")
     dirty = False
 
diff --git a/projects/bussard/src/python/bussard/reader.py b/projects/bussard/src/python/bussard/reader.py
index 08d4948..ce1c0c4 100644
--- a/projects/bussard/src/python/bussard/reader.py
+++ b/projects/bussard/src/python/bussard/reader.py
@@ -9,7 +9,10 @@ zonefiles through the parser.
 
 from types import LambdaType
 
-from bussard.gen.parser import parse as _parse, Parser  # noqa
+from bussard.gen.parser import (  # noqa
+    parse as _parse,
+    Parser,
+)
 from bussard.gen.types import *  # noqa
 
 
diff --git a/projects/bussard/test/python/bussard/test_reader.py b/projects/bussard/test/python/bussard/test_reader.py
index 253e9d2..c2dff6a 100644
--- a/projects/bussard/test/python/bussard/test_reader.py
+++ b/projects/bussard/test/python/bussard/test_reader.py
@@ -3,7 +3,12 @@ Tests of the Bussard reader.
 """
 
 import bussard.reader as t
-from bussard.reader import Actions, Parser, read, read1
+from bussard.reader import (
+    Actions,
+    Parser,
+    read,
+    read1,
+)
 
 
 def parse_word(input):
diff --git a/projects/calf/setup.py b/projects/calf/setup.py
index 2a1553e..cb8cebd 100644
--- a/projects/calf/setup.py
+++ b/projects/calf/setup.py
@@ -2,7 +2,10 @@
 
 from os import path
 
-from setuptools import find_namespace_packages, setup
+from setuptools import (
+    find_namespace_packages,
+    setup,
+)
 
 
 # Fetch the README contents
diff --git a/projects/datalog-shell/src/python/datalog/shell/__main__.py b/projects/datalog-shell/src/python/datalog/shell/__main__.py
index 6b0b605..cdf779d 100755
--- a/projects/datalog-shell/src/python/datalog/shell/__main__.py
+++ b/projects/datalog-shell/src/python/datalog/shell/__main__.py
@@ -54,7 +54,11 @@ import sys
 
 from datalog.debris import Timing
 from datalog.evaluator import select
-from datalog.reader import pr_str, read_command, read_dataset
+from datalog.reader import (
+    pr_str,
+    read_command,
+    read_dataset,
+)
 from datalog.types import (
     CachedDataset,
     Dataset,
@@ -64,8 +68,13 @@ from datalog.types import (
     TableIndexedDataset,
 )
 
-from prompt_toolkit import print_formatted_text, PromptSession
-from prompt_toolkit.formatted_text import FormattedText
+from prompt_toolkit import (
+    print_formatted_text,
+    PromptSession,
+)
+from prompt_toolkit.formatted_text import (
+    FormattedText,
+)
 from prompt_toolkit.history import FileHistory
 from prompt_toolkit.styles import Style
 from yaspin import Spinner, yaspin
diff --git a/projects/datalog/src/python/datalog/easy.py b/projects/datalog/src/python/datalog/easy.py
index b42a5b1..47d7d73 100644
--- a/projects/datalog/src/python/datalog/easy.py
+++ b/projects/datalog/src/python/datalog/easy.py
@@ -8,9 +8,18 @@ Easy because it's closer to hand, but no simpler.
 
 from typing import Sequence, Tuple
 
-from datalog.evaluator import join as __join, select as __select
+from datalog.evaluator import (
+    join as __join,
+    select as __select,
+)
 from datalog.reader import read as __read
-from datalog.types import Constant, Dataset, LTuple, LVar, PartlyIndexedDataset
+from datalog.types import (
+    Constant,
+    Dataset,
+    LTuple,
+    LVar,
+    PartlyIndexedDataset,
+)
 
 
 def read(text: str, db_cls=PartlyIndexedDataset):
diff --git a/projects/datalog/src/python/datalog/evaluator.py b/projects/datalog/src/python/datalog/evaluator.py
index 05c8e62..2369aa3 100644
--- a/projects/datalog/src/python/datalog/evaluator.py
+++ b/projects/datalog/src/python/datalog/evaluator.py
@@ -4,7 +4,13 @@ A datalog engine.
 
 from functools import reduce
 
-from datalog.types import CachedDataset, Constant, Dataset, LVar, TableIndexedDataset
+from datalog.types import (
+    CachedDataset,
+    Constant,
+    Dataset,
+    LVar,
+    TableIndexedDataset,
+)
 
 
 def match(tuple, expr, bindings=None):
diff --git a/projects/datalog/src/python/datalog/reader.py b/projects/datalog/src/python/datalog/reader.py
index 1bc120c..b283070 100644
--- a/projects/datalog/src/python/datalog/reader.py
+++ b/projects/datalog/src/python/datalog/reader.py
@@ -4,8 +4,17 @@ A datalog reader.
 
 from collections import defaultdict
 
-from datalog.parser import FAILURE, Grammar, ParseError
-from datalog.types import Constant, Dataset, LVar, Rule
+from datalog.parser import (
+    FAILURE,
+    Grammar,
+    ParseError,
+)
+from datalog.types import (
+    Constant,
+    Dataset,
+    LVar,
+    Rule,
+)
 
 
 class Actions(object):
diff --git a/projects/flowmetal/src/python/flowmetal/__main__.py b/projects/flowmetal/src/python/flowmetal/__main__.py
index 6fac27b..7fd4e13 100644
--- a/projects/flowmetal/src/python/flowmetal/__main__.py
+++ b/projects/flowmetal/src/python/flowmetal/__main__.py
@@ -3,7 +3,12 @@ The Flowmetal server entry point.
 """
 
 import click
-from flowmetal import frontend, interpreter, reaper, scheduler
+from flowmetal import (
+    frontend,
+    interpreter,
+    reaper,
+    scheduler,
+)
 
 
 @click.group()
diff --git a/projects/flowmetal/src/python/flowmetal/db/base.py b/projects/flowmetal/src/python/flowmetal/db/base.py
index 529edd4..13e8023 100644
--- a/projects/flowmetal/src/python/flowmetal/db/base.py
+++ b/projects/flowmetal/src/python/flowmetal/db/base.py
@@ -2,7 +2,10 @@
 An abstract or base Flowmetal DB.
 """
 
-from abc import abstractclassmethod, abstractmethod
+from abc import (
+    abstractclassmethod,
+    abstractmethod,
+)
 
 
 class Db(ABC):
diff --git a/projects/jobq/src/python/jobq/__init__.py b/projects/jobq/src/python/jobq/__init__.py
index 1732502..1cfb03d 100644
--- a/projects/jobq/src/python/jobq/__init__.py
+++ b/projects/jobq/src/python/jobq/__init__.py
@@ -9,7 +9,10 @@ import sqlite3
 from typing import NamedTuple, Optional as Maybe
 
 import anosql
-from anosql_migrations import run_migrations, with_migrations
+from anosql_migrations import (
+    run_migrations,
+    with_migrations,
+)
 
 
 _GET_JOB_FIELDS = """\
diff --git a/projects/jobqd/src/python/jobqd/__main__.py b/projects/jobqd/src/python/jobqd/__main__.py
index f9089f9..f61f874 100644
--- a/projects/jobqd/src/python/jobqd/__main__.py
+++ b/projects/jobqd/src/python/jobqd/__main__.py
@@ -6,7 +6,13 @@ import argparse
 import logging
 import os
 
-from flask import abort, current_app, Flask, jsonify, request
+from flask import (
+    abort,
+    current_app,
+    Flask,
+    jsonify,
+    request,
+)
 from jobq import Job, JobQueue
 
 
diff --git a/projects/kook/src/kook/client.py b/projects/kook/src/kook/client.py
index bc74fee..8596699 100644
--- a/projects/kook/src/kook/client.py
+++ b/projects/kook/src/kook/client.py
@@ -5,12 +5,22 @@ from itertools import chain
 import json
 import sys
 import time
-from typing import Any, Iterable, Optional, Tuple, Union
+from typing import (
+    Any,
+    Iterable,
+    Optional,
+    Tuple,
+    Union,
+)
 
 from kazoo.client import KazooClient
 from kazoo.exceptions import NodeExistsError
 from kazoo.protocol.states import ZnodeStat
-from kazoo.recipe.lock import Lock, ReadLock, WriteLock
+from kazoo.recipe.lock import (
+    Lock,
+    ReadLock,
+    WriteLock,
+)
 from kook.config import current_config, KookConfig
 from toolz.dicttoolz import (
     assoc as _assoc,
diff --git a/projects/lilith/src/python/lilith/__main__.py b/projects/lilith/src/python/lilith/__main__.py
index ced141d..3c5c32a 100644
--- a/projects/lilith/src/python/lilith/__main__.py
+++ b/projects/lilith/src/python/lilith/__main__.py
@@ -1,16 +1,32 @@
 """The Lilith runner."""
 
 import argparse
-from importlib.resources import read_text as resource_text
+from importlib.resources import (
+    read_text as resource_text,
+)
 import logging
 import sys
 import traceback
 
-from lilith.interpreter import Bindings, eval as lil_eval, Runtime
+from lilith.interpreter import (
+    Bindings,
+    eval as lil_eval,
+    Runtime,
+)
 from lilith.parser import parse_expr, Symbol
-from lilith.reader import Def, Module, read_buffer, read_file
-from prompt_toolkit import print_formatted_text, PromptSession
-from prompt_toolkit.formatted_text import FormattedText
+from lilith.reader import (
+    Def,
+    Module,
+    read_buffer,
+    read_file,
+)
+from prompt_toolkit import (
+    print_formatted_text,
+    PromptSession,
+)
+from prompt_toolkit.formatted_text import (
+    FormattedText,
+)
 from prompt_toolkit.history import FileHistory
 from prompt_toolkit.styles import Style
 import yaml
diff --git a/projects/lilith/src/python/lilith/interpreter.py b/projects/lilith/src/python/lilith/interpreter.py
index 91095e3..b06f25e 100644
--- a/projects/lilith/src/python/lilith/interpreter.py
+++ b/projects/lilith/src/python/lilith/interpreter.py
@@ -5,7 +5,12 @@ A quick and dirty recursive interpreter for Lilith.
 import logging
 import typing as t
 
-from lilith.parser import Apply, Args, Block, Symbol
+from lilith.parser import (
+    Apply,
+    Args,
+    Block,
+    Symbol,
+)
 from lilith.reader import Def, Import, Module
 
 
diff --git a/projects/lilith/src/python/lilith/reader.py b/projects/lilith/src/python/lilith/reader.py
index 69ee591..0a219c5 100644
--- a/projects/lilith/src/python/lilith/reader.py
+++ b/projects/lilith/src/python/lilith/reader.py
@@ -6,7 +6,11 @@ import logging
 import typing as t
 from warnings import warn
 
-from lilith.parser import Block, parse_buffer, Symbol
+from lilith.parser import (
+    Block,
+    parse_buffer,
+    Symbol,
+)
 
 
 log = logging.getLogger(__name__)
diff --git a/projects/lilith/test/python/conftest.py b/projects/lilith/test/python/conftest.py
index 9f27b7d..629585d 100644
--- a/projects/lilith/test/python/conftest.py
+++ b/projects/lilith/test/python/conftest.py
@@ -2,7 +2,10 @@
 Pytest fixtures.
 """
 
-from lilith.parser import GRAMMAR, parser_with_transformer
+from lilith.parser import (
+    GRAMMAR,
+    parser_with_transformer,
+)
 import pytest
 
 
diff --git a/projects/lilith/test/python/test_interpreter.py b/projects/lilith/test/python/test_interpreter.py
index f4e6856..ba8caf7 100644
--- a/projects/lilith/test/python/test_interpreter.py
+++ b/projects/lilith/test/python/test_interpreter.py
@@ -2,7 +2,11 @@
 
 """
 
-from lilith.interpreter import Bindings, eval, Runtime
+from lilith.interpreter import (
+    Bindings,
+    eval,
+    Runtime,
+)
 from lilith.parser import Apply, Args, Symbol
 from lilith.reader import Def, Module
 import pytest
diff --git a/projects/lilith/test/python/test_parser.py b/projects/lilith/test/python/test_parser.py
index 84c2568..9e443b9 100644
--- a/projects/lilith/test/python/test_parser.py
+++ b/projects/lilith/test/python/test_parser.py
@@ -1,6 +1,12 @@
 """tests covering the Lilith parser."""
 
-from lilith.parser import Apply, Args, Block, parse_buffer, Symbol
+from lilith.parser import (
+    Apply,
+    Args,
+    Block,
+    parse_buffer,
+    Symbol,
+)
 import pytest
 
 
diff --git a/projects/lilith/test/python/test_reader.py b/projects/lilith/test/python/test_reader.py
index 5671cfb..612e984 100644
--- a/projects/lilith/test/python/test_reader.py
+++ b/projects/lilith/test/python/test_reader.py
@@ -1,6 +1,11 @@
 """Tests covering the reader."""
 
-from lilith.parser import Apply, Args, Block, Symbol
+from lilith.parser import (
+    Apply,
+    Args,
+    Block,
+    Symbol,
+)
 from lilith.reader import Def, Module, read_buffer
 import pytest
 
diff --git a/projects/overwatch/bin/overwatchd b/projects/overwatch/bin/overwatchd
index 34556cb..3eb2ccc 100755
--- a/projects/overwatch/bin/overwatchd
+++ b/projects/overwatch/bin/overwatchd
@@ -25,8 +25,14 @@ from telnetlib import Telnet
 from threading import Event, Lock, Thread
 from time import sleep
 
-from kazoo.exceptions import ConnectionLoss, LockTimeout, SessionExpiredError
-from kazoo.handlers.threading import KazooTimeoutError
+from kazoo.exceptions import (
+    ConnectionLoss,
+    LockTimeout,
+    SessionExpiredError,
+)
+from kazoo.handlers.threading import (
+    KazooTimeoutError,
+)
 from kazoo.recipe.lock import Lock as KazooLock
 from kook.client import KookClient, lock
 
diff --git a/projects/yamlschema/src/python/yamlschema/__init__.py b/projects/yamlschema/src/python/yamlschema/__init__.py
index 1a75a3c..e313e13 100644
--- a/projects/yamlschema/src/python/yamlschema/__init__.py
+++ b/projects/yamlschema/src/python/yamlschema/__init__.py
@@ -9,7 +9,12 @@ import re
 import typing as t
 
 import yaml
-from yaml.nodes import MappingNode, Node, ScalarNode, SequenceNode
+from yaml.nodes import (
+    MappingNode,
+    Node,
+    ScalarNode,
+    SequenceNode,
+)
 
 
 log = logging.getLogger(__name__)
diff --git a/setup.cfg b/setup.cfg
index d6d9679..c8911fa 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,21 +1,17 @@
 [isort]
-line_length = 100
+line_length = 50
 indent = 4
 # 1/Vertical
 multi_line_output = 3
 lines_after_imports = 2
 default_section = THIRDPARTY
 known_localfolder = datalog
-sections = [
-    FUTURE,
-    STDLIB,
-    LOCALFOLDER,
-    THIRDPARTY,
-  ]
+sections = FUTURE,STDLIB,LOCALFOLDER,THIRDPARTY,
 
 force_sort_within_sections = 1
 force_alphabetical_sort_within_sections = 1
 combine_as_imports = 1
+include_trailing_comma = 1
 
 [distutils]
 index-servers = pypi
diff --git a/tools/python/test_licenses.py b/tools/python/test_licenses.py
index 22f43f2..07cc326 100644
--- a/tools/python/test_licenses.py
+++ b/tools/python/test_licenses.py
@@ -4,7 +4,10 @@ Validate 3rdparty library licenses as approved.
 
 import re
 
-from pkg_resources import DistInfoDistribution, working_set
+from pkg_resources import (
+    DistInfoDistribution,
+    working_set,
+)
 import pytest
 
 
diff --git a/tools/sphinx/__main__.py b/tools/sphinx/__main__.py
index 7f92055..6553a02 100644
--- a/tools/sphinx/__main__.py
+++ b/tools/sphinx/__main__.py
@@ -19,8 +19,13 @@ import livereload
 from sphinx.application import Sphinx
 from sphinx.cmd.quickstart import main as new
 from sphinx.ext.apidoc import main as apidoc
-from sphinx.ext.autosummary.generate import main as autosummary
-from sphinx.util.docutils import docutils_namespace, patch_docutils
+from sphinx.ext.autosummary.generate import (
+    main as autosummary,
+)
+from sphinx.util.docutils import (
+    docutils_namespace,
+    patch_docutils,
+)
 
 
 @click.group()