Split out of #57 as suggested there.
Symptom
Every run of the current published image starts with:
$ docker run --rm gofwd/analyze_hosts 2>&1 | head -2
[-] Please install required modules, e.g. pip3 install -r requirements.txt: No module named 'pkg_resources'
analyze_hosts version 1.16.0 starting
The visible cost is a misleading warning on every run (the modules are installed). The invisible cost is that --framework is then silently dropped in preflight_checks():
if options["framework"]:
try:
import requests
import Wappalyzer
...
except ImportError:
logging.error("Disabling --framework due to missing Python libraries")
options["framework"] = False
which is the same end state as the long-closed #41.
Cause
Four things line up:
- The guarded import block imports
Wappalyzer.
python-Wappalyzer 0.3.1 — the latest release — does import pkg_resources and pkg_resources.resource_string(__name__, "data/technologies.json").
pkg_resources ships with setuptools, and since Python 3.12 python -m venv no longer seeds setuptools into a virtualenv. The image is on Python 3.14.6 (PYTHON_VERSION in the published image config), so /opt/venv has none.
- setuptools 82.0.0 removed
pkg_resources outright, so pip install setuptools does not fix it. I checked the wheels: 81.0.0 still ships 19 pkg_resources/* files, 82.0.0 ships zero.
And chorsley/python-Wappalyzer has been archived since 2024-04, with 0.3.1 the final release — so there is no upstream fix to wait for, and bumping the pin (#50) will not help.
One nuance worth noting: because Wappalyzer is imported last in that block, requests and yaml are already bound and everything else keeps working. If the failing import were earlier in the block the program would continue with those names unbound and fail later with a NameError — e.g. read_settings() uses yaml.
Suggested fix
What we run in production, as a build-time patch on top of your image — two lines, no new dependencies, and it drops the dead dependency rather than pinning around it:
# in <site-packages>/Wappalyzer/Wappalyzer.py
-import pkg_resources
+import importlib.resources
- obj = json.loads(pkg_resources.resource_string(__name__, "data/technologies.json"))
+ obj = json.loads(
+ importlib.resources.files("Wappalyzer").joinpath("data/technologies.json").read_bytes()
+ )
importlib.resources.files() has been available since Python 3.9. Verified against a venv with setuptools 84.0.0 installed (i.e. no pkg_resources anywhere): Wappalyzer.latest() loads all 1270 technologies, and pkg_resources is never imported.
Alternatives, for completeness:
- Pin
setuptools<82 in requirements.txt. Works today, but pins an obsolete setuptools and will rot.
- Vendor or replace
python-Wappalyzer, given it is archived. Cleanest long term, much larger change.
Happy to send a PR for whichever you prefer — the sed/patch form in the Dockerfile is the smallest change, but it does mean editing an installed third-party file, so I did not want to presume.
Split out of #57 as suggested there.
Symptom
Every run of the current published image starts with:
$ docker run --rm gofwd/analyze_hosts 2>&1 | head -2 [-] Please install required modules, e.g. pip3 install -r requirements.txt: No module named 'pkg_resources' analyze_hosts version 1.16.0 startingThe visible cost is a misleading warning on every run (the modules are installed). The invisible cost is that
--frameworkis then silently dropped inpreflight_checks():which is the same end state as the long-closed #41.
Cause
Four things line up:
Wappalyzer.python-Wappalyzer0.3.1 — the latest release — doesimport pkg_resourcesandpkg_resources.resource_string(__name__, "data/technologies.json").pkg_resourcesships with setuptools, and since Python 3.12python -m venvno longer seeds setuptools into a virtualenv. The image is on Python 3.14.6 (PYTHON_VERSIONin the published image config), so/opt/venvhas none.pkg_resourcesoutright, sopip install setuptoolsdoes not fix it. I checked the wheels: 81.0.0 still ships 19pkg_resources/*files, 82.0.0 ships zero.And
chorsley/python-Wappalyzerhas been archived since 2024-04, with 0.3.1 the final release — so there is no upstream fix to wait for, and bumping the pin (#50) will not help.One nuance worth noting: because
Wappalyzeris imported last in that block,requestsandyamlare already bound and everything else keeps working. If the failing import were earlier in the block the program would continue with those names unbound and fail later with aNameError— e.g.read_settings()usesyaml.Suggested fix
What we run in production, as a build-time patch on top of your image — two lines, no new dependencies, and it drops the dead dependency rather than pinning around it:
importlib.resources.files()has been available since Python 3.9. Verified against a venv with setuptools 84.0.0 installed (i.e. nopkg_resourcesanywhere):Wappalyzer.latest()loads all 1270 technologies, andpkg_resourcesis never imported.Alternatives, for completeness:
setuptools<82inrequirements.txt. Works today, but pins an obsolete setuptools and will rot.python-Wappalyzer, given it is archived. Cleanest long term, much larger change.Happy to send a PR for whichever you prefer — the
sed/patch form in theDockerfileis the smallest change, but it does mean editing an installed third-party file, so I did not want to presume.