Thank Yous, License and Tools
Proteus is MIT-licensed. Every dependency with its real version, real license and what it is used for.
Proteus is by Jeremy Hall and released under the MIT license.
Eight runtime dependencies, two development dependencies, and no npm. That is the whole supply chain.
Every version, floor and license below is checked against the installed tree rather
than maintained by hand. scripts/check-docs-deps.py parses the tables on this page
and fails if any of them has drifted from pyproject.toml, importlib.metadata or a
real pytest run — this page shipped once claiming six runtime dependencies when
there were eight, and a test count that had drifted by more than half.
License#
MIT License
Copyright (c) 2026 Jeremy Hall
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Note The license covers the tool. Everything Proteus emits is fabricated and describes no real system. It is synthetic data for demos and testing.
Runtime dependencies#
Eight, declared in pyproject.toml. Versions below are what is installed in this
build's virtualenv, verified with:
.venv/bin/python -c "import importlib.metadata as m; print(m.version('boto3'))"
| Package | Installed | Declared floor | License | Used for |
|---|---|---|---|---|
| boto3 | 1.43.101 | >=1.35 |
Apache-2.0 | Every AWS API call: CloudFormation, Logs, X-Ray, STS, Bedrock, Pricing, S3, RUM |
| botocore | 1.43.101 | >=1.35 |
Apache-2.0 | SigV4 request signing for the raw OTLP endpoints |
| typer | 0.27.2 | >=0.12 |
MIT | The whole CLI: commands, options, the hunt sub-app, confirmation prompts |
| rich | 15.0.0 | >=13.7 |
MIT | Terminal tables, panels, the projection block and the banner |
| opentelemetry-proto | 1.44.0 | >=1.27 |
Apache-2.0 | OTLP protobuf message types for metrics, logs and traces |
| requests | 2.34.2 | >=2.32 |
Apache-2.0 | HTTP transport to the three OTLP endpoints |
| markdown-it-py | 4.2.0 | >=3.0 |
MIT | Rendering the documentation Markdown to HTML — CommonMark, plus tables and strikethrough (proteus/docsite/render.py) |
| Pygments | 2.21.0 | >=2.17 |
BSD-2-Clause | Syntax highlighting in the documentation's code blocks, with separate light and dark styles (friendly and github-dark) so fences are readable in both themes |
protobuf 7.36.2 (BSD-3-Clause) arrives as a dependency of opentelemetry-proto
and provides the protobuf runtime those generated message types need.
Two pairs in that table are there for reasons worth stating, because in both cases the naive dependency list would have been shorter and wrong.
boto3 and botocore are listed separately on purpose. boto3 is the client library, but
the OTLP endpoints are not boto3 clients — they are signed HTTP requests, and the
SigV4 signing comes from botocore directly. Losing botocore would break injection
while leaving every describe call working, which is the kind of failure worth being
able to name.
markdown-it-py and Pygments are runtime dependencies rather than a documentation
extra, and they are declared explicitly rather than relied on. Both already arrive
transitively via rich, which uses them for its own Markdown rendering and syntax
highlighting — so the build would work without declaring them, right up until a
future rich release drops one. proteus site imports both directly, so leaning on
another package's transitive tree would be a silent breakage waiting to happen. Same
argument as protobuf above, applied one layer earlier.
Transitive dependencies#
Pulled in by the eight above rather than requested directly. Twelve of them:
| Package | Installed | License | Arrives via |
|---|---|---|---|
| protobuf | 7.36.2 | BSD-3-Clause | opentelemetry-proto |
| s3transfer | 0.19.2 | Apache-2.0 | boto3 |
| jmespath | 1.1.0 | MIT | boto3, botocore |
| python-dateutil | 2.9.0.post0 | Dual BSD / Apache-2.0 | botocore |
| six | 1.17.0 | MIT | python-dateutil |
| urllib3 | 2.8.0 | MIT | botocore, requests |
| certifi | 2026.7.22 | MPL-2.0 | requests |
| charset-normalizer | 3.5.1 | MIT | requests |
| idna | 3.20 | BSD-3-Clause | requests |
| mdurl | 0.1.2 | MIT | markdown-it-py |
| shellingham | 1.5.4 | ISC | typer |
| annotated-doc | 0.0.5 | MIT | typer |
six is the only second-order entry: it arrives via python-dateutil, which arrives
via botocore. Nothing here is requested by Proteus.
That table is twelve rows on macOS and Linux and thirteen on Windows: typer
declares colorama; platform_system == "Windows", so a Windows install has one more
transitive package than this page lists. The count depends on where you install it.
Development dependencies#
| Package | Installed | Declared floor | License | Used for |
|---|---|---|---|---|
| pytest | 9.1.1 | >=8.0 |
MIT | The test suite — 535 tests |
| pytest-cov | 7.1.0 | >=5.0 |
MIT | Coverage measurement |
| coverage | 7.16.1 | — | Apache-2.0 | Arrives via pytest-cov |
.venv/bin/python -m pytest
535 passed in 18.14s
Note No
-q.pyproject.tomlalready setsaddopts = "-q", so passing it again escalates to doubly-quiet and suppresses theN passedsummary line entirely — the command prints the progress dots and nothing else. An earlier version of this page showed-qnext to a summary that command cannot produce.
No npm#
The Web GUI has no JavaScript dependencies at all. There is no package.json
anywhere in the repository, no lockfile, and no build step. It is vanilla ES modules
under proteus/web/static/js/, hand-written CSS, and a Python stdlib HTTP server.
That is a deliberate trade. It costs some conveniences a framework would give for
free. In exchange there is nothing to install, nothing to compile, no transitive
dependency tree to audit, and nothing that can rot while the project sits unused.
Edit a .js file, reload the page, see the change.
Services and specifications#
Proteus is a client for other people's work. Credit where it belongs:
Amazon CloudWatch and CloudWatch Omni are the target. Proteus speaks OTLP
rather than pushing counters because a span can state a dependency and a metric
datapoint cannot — thirteen fields across MetricDatum, Dimension and Entity, and
none of them names a second endpoint. That is the fact the tool is shaped around, and it
is why resource attributes and peer.service are load-bearing rather than decorative.
What Omni derives from a metric entity is not asserted here; it has not been tested from
this project.
AWS X-Ray receives the traces, through the OTLP endpoint at
https://xray.{region}.amazonaws.com/v1/traces. Transaction Search with destination
CloudWatchLogs is what makes that endpoint accept anything.
CloudWatch RUM receives the browser and mobile events.
Amazon Bedrock powers chat and hunt. Both only ever edit the world model —
never the telemetry — which is what keeps output deterministic and reproducible from
a model plus a seed.
OpenTelemetry, and specifically the OTLP specification and the semantic
conventions. The convention names Proteus emits — service.name,
service.namespace, deployment.environment, cloud.provider, cloud.region,
k8s.cluster.name, k8s.pod.name, host.name, db.system, messaging.system,
and the gen_ai.* family for agent workloads — are all theirs. Following them
rather than inventing names is why the service map populates.
The AWS Pricing API supplies the seven rates behind every cost projection, so the estimate reflects published list price rather than a number someone typed in once and forgot. Where a rate cannot be resolved, the built-in fallback table is used and the projection says so. The rates come from the live API, but the pessimism is Proteus's own — see the cost guard.
AWS CloudFormation provisions the scaffolding. Using CloudFormation rather than
direct API calls buys drift detection, an existence check, and a fingerprint output
that lets doctor tell you the estate has moved ahead of what was deployed.
Python 3.12 and its standard library, which is doing more work here than the dependency list suggests — including the entire web server.
Thank you#
To everyone who filed the AWS documentation that made the limits table on the
Appendix possible, and to whoever wrote the note
that the OTLP logs endpoint requires x-aws-log-group and x-aws-log-stream
headers. That one saved a day.
To the maintainers of the twenty-three packages above — eight asked for, twelve that came with them, three more for the tests — several of whom are volunteers keeping load-bearing infrastructure alive for free.
And to everyone who ran a demo that fell over and then said out loud what broke. Most of Troubleshooting started that way.