CLI tool
KimiNewt/pyshark avatar
KimiNewt/pyshark

pyshark: tshark does the parsing, Python reads the XML it exports

Python wrapper for tshark, allowing python packet parsing using wireshark dissectors

2,499 stars452 forksPythonMIT

At a glance

What is it?
pyshark is KimiNewt's MIT licensed Python wrapper around the tshark command line utility, used to read capture files, live interfaces, ring buffers and remote hosts with the Wireshark dissectors installed on your machine. Its own files are more telling than its feature list: the README states the maintainer has little time for the package, the newest tag is v0.6 from April 2023, and the usage example still prints like Python 2.
Who is it for?
pyshark earns its place when you want Wireshark dissector output inside Python and do not mind shelling out to tshark, and its parameter lists are unusually explicit about what each capture class accepts, including the gaps. Read the tradeoffs before adopting it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 5, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Python never parses the packets, tshark exports the XML

The library's whole design is one sentence from its own description: it does not parse any packets, it uses tshark's ability to export XML and parses that. The tshark binary is therefore a hard runtime requirement, and tshark_path exists in every capture class so you can point at a specific binary when it is not on PATH. Which layers you can reach depends on the dissectors installed on the machine doing the capture, not on anything bundled here. A file capture looks like this:

python
>>> import pyshark
>>> cap = pyshark.FileCapture('/tmp/mycapture.cap')
>>> cap
<FileCapture /tmp/mycapture.cap (589 packets)>

The object repr already shows how much work happens before you touch a packet: 589 packets counted up front. display_filter is a Wireshark display filter applied before reading, only_summaries produces summaries that are much faster but include very little information, disable_protocol turns off protocol detection and needs tshark newer than version 2, and keep_packets controls whether packets survive being consumed by next() so that large captures do not grow in memory.

The install path has two shapes and the git one runs setup.py from src

Two routes are documented. The short one is a single command from PyPI:

bash
pip install pyshark

The longer one clones the repository and runs the packaging script from inside src:

bash
git clone https://github.com/KimiNewt/pyshark.git
cd pyshark/src
python setup.py install

The tree explains why the second route needs that extra directory: the top level holds .github/, .gitignore, LICENSE.txt, README.md, requirements.txt, src/ and tests/, with the packaging script reached through src rather than the repository root. The licence file is LICENSE.txt and the package is MIT. Python 3.7 and up is the supported line, and the Python 2 version is not in this repository at all: it lives in a separate project called pyshark-legacy. The extended documentation sits at http://kiminewt.github.io/pyshark, an unencrypted address in the same README that otherwise gives you two ways to install the thing.

The file example prints like Python 2 while the project claims 3.7+

The capture example in the README cannot run on the Python the same README asks you to use:

python
>>> print cap[0]
Packet (Length: 698)
Layer ETH:
        Destination: BLANKED
        Source: BLANKED
        Type: IP (0x0800)

print cap[0] is the Python 2 statement form, which is a syntax error on Python 3, and the project says Python 3.7 and up is supported while Python 2 has been pushed out to pyshark-legacy. So the one complete end to end example in the documentation is written for the interpreter the project no longer supports. The output beside it also shows the shape of what you get: a packet length, then one block per layer, with the two MAC addresses blanked in the published sample and the IP header expanded field by field down to Time to live: 1. Later examples in the same file use the print() call form, so the inconsistency sits inside one document rather than across versions of it.

Remote capture is the one class with no display filter

LiveCapture and LiveRingCapture both take display_filter. RemoteCapture does not. Its parameter list is remote_host, remote_interface, remote_port, bpf_filter, only_summaries, disable_protocol, decryption_key, encryption_type and tshark_path, so on a remote host you can cut the traffic with a BPF filter before reading and you can cut the parsing with only_summaries, but there is no Wireshark display filter in the list. The class expects rpcapd to be running on the far side:

python
>>> capture = pyshark.RemoteCapture('192.168.1.101', 'eth0')
>>> capture.sniff(timeout=50)
>>> capture

remote_interface is also where the platform matters, because the documentation warns that on Windows it is not the device display name but the true interface name of the form \\Device\\NPF_.. . The same README says the package is tested on windows/linux, and it adds a Mac OS X section anyway, since a Python 3.7+ package on macOS needs work the Windows and Linux paths do not.

Decryption takes three standards and defaults to the pairwise key

decryption_key and encryption_type appear in all four capture classes, which makes decryption a property of the capture object rather than something applied afterwards to packets. The accepted values are narrow: encryption_type must be either WEP, WPA-PWD or WPA-PWK, and it defaults to WPA-PWK. That default is worth pausing on, because WPA-PWK is the pairwise key and WPA-PWD is the passphrase form people usually have in hand, so a caller who passes a passphrase without also setting encryption_type gets a mismatch between key and algorithm. The parameter is documented in prose in three separate option lists rather than in one shared table, which is also why the same sentence about the three accepted values is repeated under each class. Everything else about the key handling is left to tshark, since this package never touches the traffic bytes itself.

The ring buffer defaults to a single 1024 kB file in /tmp

LiveRingCapture is the live class with a bounded footprint, and its three own parameters carry defaults that decide where packets go and how fast the disk fills:

python
>>> capture = pyshark.LiveRingCapture(interface='eth0')
>>> capture.sniff(timeout=50)
>>> capture
<LiveCapture (5 packets)>

ring_file_size is the size of the ring file in kB and defaults to 1024, num_ring_files is how many ring files to keep and defaults to 1, and ring_file_name defaults to /tmp/pyshark.pcap. So a default ring capture keeps one megabyte in a predictable path under /tmp, which matters on a long running capture because the file is reused rather than growing without bound. Everything else on that class mirrors LiveCapture, including bpf_filter, output_file for saving what it sniffs, and only_summaries, which the documentation repeats in every class as the switch to trade detail for speed.

requirements.txt is a test list, and the macOS fix names a different XML package

The only dependency file in the tree opens with a comment that says these are development requirements, required only for testing:

code
# Development requirements. Only required for testing
appdirs
py
pytest
lxml
packaging
termcolor

Six entries, none of them a parser and none of them a Wireshark binding, which fits a package whose runtime dependency is an external binary rather than a library. That file also names lxml, while the macOS section of the README tells you to install a different thing:

bash
xcode-select --install
pip install libxml

Two XML packages, two names, one in the test requirements and one in the platform fix. The macOS note says the libxml install can be unexpected, that a clang error or a libxml error message means you need it, and that you will have to accept a licence agreement for the command line tools through a dialog in the graphical interface before pip runs. None of that applies to the pip install pyshark path on Windows or Linux.

The newest tag is v0.6 from April 2023, the last push is 2026-03-22

Dates here are worth reading together. The releases are v0.6 on 2023-04-26, v0.5.3 on 2022-07-14 and v0.5.2 on 2022-07-09, so no 0.6 patch has been published in three years and the packaged line a pip install resolves to is the April 2023 one. The last recorded push to the repository is 2026-03-22, and the repository is not archived, so work continues on the default branch without new tags to mark it. The README says the same thing in its own words: it opens by asking for contributors because the author has a hard time finding time to maintain and enhance the package. On version support it makes no promise beyond all modern versions of tshark and Wireshark being supported with some features possibly unavailable on older ones, and it names no minimum Wireshark build for any feature, which is the gap to watch when a dissector you need is newer than the tshark on a given machine.

Editorial conclusion

pyshark earns its place when you want Wireshark dissector output inside Python and do not mind shelling out to tshark, and its parameter lists are unusually explicit about what each capture class accepts, including the gaps. Read the tradeoffs before adopting it. The parsing cost is tshark's XML, so large captures are slow unless you use only_summaries or keep_packets, remote capture needs rpcapd running on the far side, and decryption only accepts WEP, WPA-PWD or WPA-PWK with WPA-PWK as the default. Check the Wireshark version on your target machines against the features you need, replace the Python 2 print in the example before you copy it, and pin the version you install: the newest packaged release is v0.6 from 2023-04-26 even though the default branch took a push on 2026-03-22.

Frequently asked questions

What is PyShark used for?

Parsing packets in Python with the Wireshark dissectors you already have installed, from a capture file (PCAP, PCAP-NG or a TShark XML) or from a live interface. It does not parse anything itself: tshark exports XML and the library reads that.

What are the differences between PyShark and Tshark?

tshark is the Wireshark command line utility that does the dissecting. pyshark is the Python layer on top of it: it calls tshark to export XML and reads that output, so the layers you see depend on the dissectors installed on the machine running the capture.

Can I use Wireshark with Python?

Yes, through tshark. The project parses using the Wireshark dissectors installed on your machine, with tshark_path available in every capture class to point at a specific binary. Extended documentation is published at kiminewt.github.io/pyshark.

How do I install pyshark?

Either pip install pyshark from PyPI, or clone the repository, change into pyshark/src and run python setup.py install. Python 3.7 and up is supported; the Python 2 version lives in a separate project, pyshark-legacy.

Does pyshark install on Windows?

The project says it is tested on windows/linux and gives pip install pyshark as the route for all platforms, with no Windows specific step. For remote capture on Windows, remote_interface takes the true interface name of the form \\Device\\NPF_.. rather than the device display name.

What alternatives to pyshark are there?

The repository names no other parsing library as a replacement. It points only at pyshark-legacy for the unsupported Python 2 line, and its argument for this package is that it does not parse packets itself but reads the XML tshark exports.

Official sources

  1. Issues
  2. KimiNewt/pyshark on GitHub
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/kiminewt-pyshark.svg)](https://hysenlabs.com/projects/kiminewt-pyshark)