Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d7556ff
chore(deps): bump the all-dependencies group with 4 updates (#609)
dependabot[bot] Mar 18, 2026
3ae975f
Update documentation for 3.0 release
gijzelaerr Mar 18, 2026
d779ba3
Add note explaining the historical python-snap7 name
gijzelaerr Mar 18, 2026
f880d8c
Add contributors to 3.0.0 release notes
gijzelaerr Mar 18, 2026
4c52bcb
Add coverage badge and coverage threshold (#637)
gijzelaerr Mar 20, 2026
67713e2
Add comprehensive tests for partner.py (57% -> 84% coverage) (#645)
gijzelaerr Mar 20, 2026
60047da
Accept memoryview in setter and getter type annotations (#647)
gijzelaerr Mar 20, 2026
6ccacf5
Add integration tests for server block operations and USERDATA handle…
gijzelaerr Mar 20, 2026
4bded55
Add tests for snap7/logo.py to improve coverage from 53% to 97% (#643)
gijzelaerr Mar 20, 2026
5443402
Add tests to improve coverage from 78% to 84% (#642)
gijzelaerr Mar 20, 2026
fe6df93
Add native AsyncClient with asyncio support (#593)
gijzelaerr Mar 20, 2026
d52b70b
Add S7CommPlus protocol scaffolding for S7-1200/1500 (#603)
gijzelaerr Mar 20, 2026
a2561a2
Enhanced CLI tools for PLC interaction (#631)
gijzelaerr Mar 20, 2026
ab09964
Add typed DB access methods for common S7 data types (#632)
gijzelaerr Mar 20, 2026
108a107
Add protocol conformance test suite (#633)
gijzelaerr Mar 20, 2026
f0634f8
Add examples cookbook and troubleshooting documentation (#610)
gijzelaerr Mar 20, 2026
b16c707
Cleanup: consolidate tests, docs, and README (#648)
gijzelaerr Mar 20, 2026
76acf91
Restructure docs into logical sections (#649)
gijzelaerr Mar 20, 2026
0dbcda4
chore(deps): bump the all-dependencies group with 5 updates (#650)
dependabot[bot] Mar 23, 2026
13da80d
Add property-based testing with Hypothesis (#636)
gijzelaerr Mar 24, 2026
5c012be
Remove Codecov integration (#653)
gijzelaerr Mar 24, 2026
11dbb86
Add get_ulint and get_lint to snap7.util exports (#652)
gijzelaerr Mar 24, 2026
40d21ed
Add S7CommPlus V2 protocol support (TLS + IntegrityId) (#646)
gijzelaerr Mar 24, 2026
175750c
Add PROFINET DCP network discovery (#634)
gijzelaerr Mar 24, 2026
6342133
Add heartbeat monitoring and auto-reconnect with exponential backoff …
gijzelaerr Mar 24, 2026
252a83d
Add .hypothesis to .gitignore
gijzelaerr Mar 25, 2026
c6fdd85
Replace pip with uv across all CI workflows (#658)
gijzelaerr Mar 25, 2026
f48958c
Update documentation for heartbeat, S7CommPlus V2, and discovery (#654)
gijzelaerr Mar 25, 2026
667f97c
Improve test coverage for recent features (#655)
gijzelaerr Mar 25, 2026
2c94acf
Add TLS support to S7CommPlus async client (#656)
gijzelaerr Mar 25, 2026
ceefe5d
Complete S7CommPlus V1 session handshake by echoing ServerSessionVersion
gijzelaerr Mar 27, 2026
bf1ecfd
Complete S7CommPlus V1 session handshake by echoing ServerSessionVers…
gijzelaerr Mar 27, 2026
af94ba3
chore(deps): bump requests from 2.32.5 to 2.33.0 (#660)
dependabot[bot] Mar 27, 2026
d1199f5
Move S7CommPlus into s7/ package, simplify to 2-layer architecture
gijzelaerr Mar 27, 2026
b4f73fe
Merge origin/master into s7-unified-package
gijzelaerr Mar 27, 2026
adacd76
Fix return types for drop-in compatibility and update docs
gijzelaerr Mar 27, 2026
9180d4f
chore(deps): bump cryptography from 46.0.5 to 46.0.6
dependabot[bot] Mar 29, 2026
a4f2921
chore(deps): bump actions/deploy-pages in the all-actions group
dependabot[bot] Mar 30, 2026
8a42362
chore(deps): bump the all-dependencies group with 5 updates
dependabot[bot] Mar 30, 2026
6e3b644
chore(deps): bump pygments from 2.19.2 to 2.20.0
dependabot[bot] Mar 30, 2026
651ca49
Update README with restructured landing page and 3.1 release notes
gijzelaerr Apr 1, 2026
066ba77
Merge pull request #662 from gijzelaerr/s7-unified-package
gijzelaerr Apr 1, 2026
770e695
Merge pull request #663 from gijzelaerr/dependabot/uv/cryptography-46…
gijzelaerr Apr 1, 2026
6b4856c
Merge pull request #664 from gijzelaerr/dependabot/github_actions/all…
gijzelaerr Apr 1, 2026
919ba3f
Merge pull request #665 from gijzelaerr/dependabot/uv/all-dependencie…
gijzelaerr Apr 1, 2026
a2a2044
Merge pull request #666 from gijzelaerr/dependabot/uv/pygments-2.20.0
gijzelaerr Apr 1, 2026
458f200
Fix pre-3.0 documentation link to correct Read The Docs tag
gijzelaerr Apr 1, 2026
62e9fa3
Fix pre-3.0 docs link to 2.1.1
gijzelaerr Apr 1, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions .github/workflows/doc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ jobs:
with:
enable-cache: true
- name: Install dependencies
run: |
uv venv
uv pip install ".[doc,cli]"
run: uv sync --extra doc --extra cli
- name: Build documentation
run: uv run sphinx-build -N -bhtml doc/ doc/_build -W
- name: Upload Pages artifact
Expand All @@ -46,4 +44,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
uses: actions/deploy-pages@v5
8 changes: 5 additions & 3 deletions .github/workflows/publish-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install build
run: pip install build
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Build distribution
run: python -m build
run: uv build
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
Expand Down
8 changes: 5 additions & 3 deletions .github/workflows/publish-test-pypi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ jobs:
uses: actions/setup-python@v6
with:
python-version: "3.12"
- name: Install build
run: pip install build
- name: Install uv
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Build distribution
run: python -m build
run: uv build
- name: Upload artifact
uses: actions/upload-artifact@v7
with:
Expand Down
6 changes: 1 addition & 5 deletions .github/workflows/source-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,9 @@ jobs:
uses: astral-sh/setup-uv@v7
with:
enable-cache: true
- name: Install build tools
run: |
uv venv
uv pip install build
- name: Create source tarball
run: |
uv run python -m build . --sdist
uv build --sdist

- name: Upload artifacts
uses: actions/upload-artifact@v7
Expand Down
12 changes: 2 additions & 10 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,6 @@ jobs:
with:
enable-cache: true
- name: Install dependencies
run: |
uv venv --python python${{ matrix.python-version }}
uv pip install ".[test]"
run: uv sync --extra test --extra s7commplus --python python${{ matrix.python-version }}
- name: Run pytest
run: uv run pytest --cov=snap7 --cov-report=xml --cov-report=term
- name: Upload coverage report
if: matrix.python-version == '3.13' && matrix.runs-on == 'ubuntu-24.04'
uses: actions/upload-artifact@v7
with:
name: coverage-report
path: coverage.xml
run: uv run pytest --cov=snap7 --cov-report=term
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,4 @@ venv*/
snap7.dll

.claude/
.hypothesis/
26 changes: 24 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,43 @@ CHANGES
-----

Major release: python-snap7 is now a pure Python S7 communication library.
This version completely breaks with the previous approach of wrapping the C snap7
shared library. The entire S7 protocol stack is now implemented in pure Python,
greatly improving portability and making it easier to install and extend.

* **Breaking**: The C snap7 library is no longer required or used
* Complete rewrite of the S7 protocol stack in pure Python
* Native Python implementation of TPKT (RFC 1006) and COTP (ISO 8073) layers
* Native S7 protocol PDU encoding/decoding
* Pure Python server implementation for testing and simulation
* No platform-specific binary dependencies
* No platform-specific binary dependencies — works on any platform that runs Python
* Improved error handling and connection management
* Full type annotations with mypy strict mode
* CLI interface for running an S7 server emulator (`pip install "python-snap7[cli]"`)

If you experience issues with 3.0, pin to the last pre-3.0 release:
If you experience issues with 3.0, please report them on the
[issue tracker](https://github.com/gijzelaerr/python-snap7/issues) with a clear
description and the version you are using. As a workaround, pin to the last
pre-3.0 release:

$ pip install "python-snap7<3"

### Thanks

Special thanks to the following people for testing, reporting issues, and providing
feedback during the 3.0 development:

* [@lupaulus](https://github.com/lupaulus) — extensive testing and bug reports
* [@spreeker](https://github.com/spreeker) — testing and feedback
* [@nikteliy](https://github.com/nikteliy) — review and feedback on the rewrite
* [@amorelettronico](https://github.com/amorelettronico) — testing
* [@razour08](https://github.com/razour08) — testing
* [@core-engineering](https://github.com/core-engineering) — bug reports (#553)
* [@AndreasScharf](https://github.com/AndreasScharf) — bug reports (#572)
* [@Robatronic](https://github.com/Robatronic) — bug reports (#574)
* [@hirotasoshu](https://github.com/hirotasoshu) — feedback (#545)
* [@PoitrasJ](https://github.com/PoitrasJ) — bug reports (#479)

1.2
---

Expand Down
42 changes: 32 additions & 10 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Python-snap7 is a pure Python S7 communication library for interfacing with Siem

## Key Architecture

### snap7/ — Legacy S7 protocol (S7-300/400, PUT/GET on S7-1200/1500)
- **snap7/client.py**: Main Client class for connecting to S7 PLCs
- **snap7/server.py**: Server implementation for PLC simulation
- **snap7/logo.py**: Logo PLC communication
Expand All @@ -19,6 +20,20 @@ Python-snap7 is a pure Python S7 communication library for interfacing with Siem
- **snap7/type.py**: Type definitions and enums (Area, Block, WordLen, etc.)
- **snap7/error.py**: Error handling and exceptions

### s7/ — Unified client with S7CommPlus + legacy fallback
- **s7/client.py**: Unified Client — tries S7CommPlus, falls back to snap7.Client
- **s7/async_client.py**: Unified AsyncClient — same pattern, async
- **s7/server.py**: Unified Server wrapping both legacy and S7CommPlus
- **s7/_protocol.py**: Protocol enum (AUTO/LEGACY/S7COMMPLUS)
- **s7/_s7commplus_client.py**: Pure S7CommPlus sync client (internal)
- **s7/_s7commplus_async_client.py**: Pure S7CommPlus async client (internal)
- **s7/_s7commplus_server.py**: S7CommPlus server emulator (internal)
- **s7/connection.py**: S7CommPlus low-level connection
- **s7/protocol.py**: S7CommPlus protocol constants/enums
- **s7/codec.py**: S7CommPlus encoding/decoding
- **s7/vlq.py**: Variable-Length Quantity encoding
- **s7/legitimation.py**: Authentication helpers

## Implementation Details

### Protocol Stack
Expand All @@ -41,24 +56,31 @@ The library implements the complete S7 protocol stack:
- Block operations (list, info, upload, download)
- Date/time operations

### Usage
### Usage (unified s7 package — recommended for S7-1200/1500)

```python
from s7 import Client

client = Client()
client.connect("192.168.1.10", 0, 1) # auto-detects S7CommPlus vs legacy
data = client.db_read(1, 0, 4)
client.disconnect()
```

### Usage (legacy snap7 package — S7-300/400)

```python
import snap7

# Create and connect client
client = snap7.Client()
client.connect("192.168.1.10", 0, 1)

# Read/write operations
data = client.db_read(1, 0, 4)
client.db_write(1, 0, bytearray([1, 2, 3, 4]))

# Memory area access
marker_data = client.mb_read(0, 4)
client.mb_write(0, 4, bytearray([1, 2, 3, 4]))

# Disconnect
client.disconnect()
```

Expand Down Expand Up @@ -98,15 +120,15 @@ pytest tests/test_client.py
### Code Quality
```bash
# Type checking
mypy snap7 tests example
mypy snap7 s7 tests example

# Linting and formatting check
ruff check snap7 tests example
ruff format --diff snap7 tests example
ruff check snap7 s7 tests example
ruff format --diff snap7 s7 tests example

# Auto-format code
ruff format snap7 tests example
ruff check --fix snap7 tests example
ruff format snap7 s7 tests example
ruff check --fix snap7 s7 tests example
```

### Development with tox
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ doc: .venv/bin/sphinx-build

.PHONY: check
check: .venv/bin/pytest
uv run ruff check snap7 tests example
uv run ruff format --diff snap7 tests example
uv run ruff check snap7 s7 tests example
uv run ruff format --diff snap7 s7 tests example

.PHONY: ruff
ruff: .venv/bin/tox
Expand Down
102 changes: 88 additions & 14 deletions README.rst
Original file line number Diff line number Diff line change
@@ -1,25 +1,32 @@
About
=====
.. image:: https://img.shields.io/pypi/v/python-snap7.svg
:target: https://pypi.org/project/python-snap7/

Python-snap7 is a pure Python S7 communication library for interfacing with Siemens S7 PLCs.
.. image:: https://img.shields.io/pypi/pyversions/python-snap7.svg
:target: https://pypi.org/project/python-snap7/

Python-snap7 is tested with Python 3.10+, on Windows, Linux and OS X.
.. image:: https://img.shields.io/github/license/gijzelaerr/python-snap7.svg
:target: https://github.com/gijzelaerr/python-snap7/blob/master/LICENSE

The full documentation is available on `Read The Docs <https://python-snap7.readthedocs.io/en/latest/>`_.
.. image:: https://github.com/gijzelaerr/python-snap7/actions/workflows/test.yml/badge.svg
:target: https://github.com/gijzelaerr/python-snap7/actions/workflows/test.yml

.. image:: https://readthedocs.org/projects/python-snap7/badge/
:target: https://python-snap7.readthedocs.io/en/latest/

Version 3.0 - Breaking Changes
===============================

Version 3.0 is a major release that rewrites python-snap7 as a pure Python
implementation. The C snap7 library is no longer required.
python-snap7
============

This release may contain breaking changes. If you experience issues, you can
pin to the last pre-3.0 release::
Python-snap7 is a pure Python S7 communication library for interfacing with
Siemens S7 PLCs. It supports Python 3.10+ and runs on Windows, Linux, and macOS
without any native dependencies.

$ pip install "python-snap7<3"
The name "python-snap7" is historical — the library originally started as a
Python wrapper around the `Snap7 <http://snap7.sourceforge.net/>`_ C library.
As of version 3.0, the C library is no longer used, but the name is kept for
backwards compatibility.

The latest stable pre-3.0 release is version 2.1.0.
The full documentation is available on `Read The Docs <https://python-snap7.readthedocs.io/en/latest/>`_.


Installation
Expand All @@ -29,4 +36,71 @@ Install using pip::

$ pip install python-snap7

No native libraries or platform-specific dependencies are required - python-snap7 is a pure Python package that works on all platforms.
No native libraries or platform-specific dependencies are required — python-snap7
is a pure Python package that works on all platforms.


Version 3.0 — Pure Python Rewrite
==================================

Version 3.0 was a ground-up rewrite of python-snap7. The library no longer wraps
the C snap7 shared library — instead, the entire S7 protocol stack (TPKT, COTP,
and S7) is implemented in pure Python.

* **Portability**: No more platform-specific shared libraries (``.dll``, ``.so``, ``.dylib``).
Works on any platform that runs Python — including ARM, Alpine Linux, and other
environments where the C library was difficult or impossible to install.
* **Easier installation**: Just ``pip install python-snap7``. No native dependencies,
no compiler toolchains, no manual library setup.
* **Easier to extend**: New features and protocol support can be added directly in Python.

**If you experience issues with 3.0:**

1. Please report them on the `issue tracker <https://github.com/gijzelaerr/python-snap7/issues>`_.
2. As a workaround, you can pin to the last pre-3.0 release::

$ pip install "python-snap7<3"

Documentation for pre-3.0 versions is available at
`Read The Docs <https://python-snap7.readthedocs.io/en/2.1.1/>`_.


Version 3.1 — S7CommPlus Protocol Support (unreleased)
=======================================================

Version 3.1 adds support for the S7CommPlus protocol (up to V3), which is required
for communicating with newer Siemens S7-1200 and S7-1500 PLCs that have PUT/GET
disabled. This is fully backwards compatible with 3.0.

The biggest change is the new ``s7`` module, which is now the recommended entry point
for connecting to any supported S7 PLC::

from s7 import Client

client = Client()
client.connect("192.168.1.10", 0, 1) # auto-detects S7CommPlus vs legacy S7
data = client.db_read(1, 0, 4)
client.disconnect()

The ``s7.Client`` automatically tries S7CommPlus first, and falls back to legacy S7
if the PLC does not support it. The existing ``snap7.Client`` continues to work
unchanged for legacy S7 connections.

**Help us test!** Version 3.1 needs more real-world testing before release. If you
have access to any of the following PLCs, we would greatly appreciate testing and
feedback:

* S7-1200 (any firmware version)
* S7-1500 (any firmware version)
* S7-1500 with TLS enabled
* S7-300
* S7-400
* S7-1200/1500 with PUT/GET disabled (S7CommPlus-only)
* LOGO! 0BA8 and newer

Please report your results — whether it works or not — on the
`issue tracker <https://github.com/gijzelaerr/python-snap7/issues>`_.

To install the development version::

$ pip install git+https://github.com/gijzelaerr/python-snap7.git@master
49 changes: 49 additions & 0 deletions doc/API/async_client.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
AsyncClient
===========

.. warning::

The ``AsyncClient`` is **experimental**. The API may change in future
releases. If you encounter problems, please `open an issue
<https://github.com/gijzelaerr/python-snap7/issues>`_.

The :class:`~snap7.async_client.AsyncClient` provides a native ``asyncio``
interface for communicating with Siemens S7 PLCs. It has feature parity with
the synchronous :class:`~snap7.client.Client` and is safe for concurrent use
via ``asyncio.gather()``.

Quick start
-----------

.. code-block:: python

import asyncio
import snap7

async def main():
async with snap7.AsyncClient() as client:
await client.connect("192.168.1.10", 0, 1)
data = await client.db_read(1, 0, 4)
print(data)

asyncio.run(main())

Concurrent reads
----------------

An internal ``asyncio.Lock`` serialises each send/receive cycle so that
multiple coroutines can safely share a single connection:

.. code-block:: python

results = await asyncio.gather(
client.db_read(1, 0, 4),
client.db_read(1, 10, 4),
)

API reference
-------------

.. automodule:: snap7.async_client
:members:
:exclude-members: AsyncISOTCPConnection
Loading