Conversation
… the posts The 2017-2018 notebooks now run on Python 3.10+ with current pandas, matplotlib and pyshark (which needs its own event loop on Python 3.12+ and inside Jupyter). A new notebook redoes the HTTP hunts with ParseZeekLogs and pandas and also runs on Zeek 8.2.2 TSV and JSON logs. The four Threat Hunting with Python posts are recovered from the Wayback Machine and the live Dragos copies into docs/ with their images. uv project, ruff lint of code cells, and a GitHub Actions workflow that executes every notebook. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
pyplotimport,list(dict.keys())for display,except AttributeErrorinstead of bare excepts. Outputs re-executed with pandas 3 and matplotlib 3.11; the 299-row suspicious-records CSV comes out identical.asyncio.get_event_loop()creates a loop and callsset_child_watcher, both gone in 3.12+/3.14, and it cannot run inside Jupyter's already-running loop. The TDS notebook now reads the capture in a worker thread with its own loop. Verified against tshark 4.6.8.Detecting Nmap Behavior with ParseZeekLogs.ipynb: the two HTTP hunts redone with ParseZeekLogs and pandas, kept alongside the originals. Also executed against Zeek 8.2.2http.login TSV and JSON form (from the ParseZeekLogs corpus) to confirm it handles current logs; the bundled 2015 log stays so results match the posts.docs/: Prologue, Part 2, Part 3 and Part 4 of Threat Hunting with Python, text from the Wayback Machine copies of dgunter.com, images from the live Dragos syndication (WebP converted to PNG) and Wayback for the WordPress-hosted ones. 22 images, every link checked.pyproject.toml+uv.lockpinning the notebook dependencies on Python 3.14, ruff linting the code cells natively (E501 ignored for the two historical notebooks), and a GitHub Actions workflow that installs tshark, lints, executes every notebook and fails on any error or stderr output..idea/ignored. Narrative README with a notebook-to-post table; GitHub description and topics set.Why not SonarCloud
Sonar does not analyse
.ipynb, and there is no package or test suite here, so a quality gate would measure nothing. Executing the notebooks in CI is the meaningful check.Verification
All four notebooks execute with zero errors and zero stderr output locally;
uv run ruff check .is clean. Zeek 8.2.2 run over the TDS pcap produces onlyconn.log(no TDS analyzer exists in Zeek), which is why that notebook stays on pyshark.🤖 Generated with Claude Code