![Testing](https://github.com/dmachard/python-framestream/workflows/Testing/badge.svg) ![Build](https://github.com/dmachard/python-framestream/workflows/Build/badge.svg) ![Pypi](https://github.com/dmachard/python-framestream/workflows/PyPI/badge.svg)
# Frame Streams implementation in Python
Frame Streams is a lightweight, binary-clean protocol that allows for the transport of arbitrarily encoded data payload sequences with minimal framing overhead.
This package provides a pure Python implementation based on https://github.com/farsightsec/fstrm/.
## Installation
![python 3.12.x](https://img.shields.io/badge/python%203.12.x-tested-blue) ![python 3.11.x](https://img.shields.io/badge/python%203.11.x-tested-blue) ![python 3.10.x](https://img.shields.io/badge/python%203.10.x-tested-blue) ![python 3.9.x](https://img.shields.io/badge/python%203.9.x-tested-blue) ![python 3.8.x](https://img.shields.io/badge/python%203.8.x-tested-blue)
This module can be installed from [pypi](https://pypi.org/project/fstrm/) website
```python
pip install fstrm
```
## Example
The example shows how to read raw data and decode-it with the fstrsm library.
```python
import fstrm
import asyncio
class FstrmServerProtocol(asyncio.Protocol):
def __init__(self, handshake, data_recv, content_type=b"plaintext"):
self.fstrm = fstrm.FstrmCodec()
self.content_type = content_type
self.data_recv = data_recv
self.handshake = handshake
self.handshake_accept_done = False
def connection_made(self, transport):
self.transport = transport
def data_received(self, data):
if not self.handshake.done():
if not self.handshake_accept_done:
if self.fstrm.is_ctrlready(data):
self.transport.write(self.fstrm.encode_ctrlaccept(self.content_type))
self.handshake_accept_done = True
else:
if self.fstrm.is_ctrlstart(data):
self.handshake.set_result(True)
else:
payload = self.fstrm.is_data(data)
# do someting with the payload...
if payload:
self.data_recv.set_result(payload)
class FstrmClientProtocol(asyncio.Protocol):
def __init__(self, handshake, content_type=b"plaintext"):
self.fstrm = fstrm.FstrmCodec()
self.content_type = content_type
self.handshake = handshake
self.transport = None
def connection_made(self, transport):
self.transport = transport
self.transport.write(self.fstrm.encode_ctrlready(self.content_type))
def data_received(self, data):
if not self.handshake.done():
if self.fstrm.is_ctrlaccept(data):
self.transport.write(self.fstrm.encode_ctrlstart(self.content_type))
self.handshake.set_result(True)
def send_data(self, data):
payload = self.fstrm.encode_data(data)
self.transport.write(payload)
async def run(loop):
# Create server and client
data_recv = loop.create_future()
hanshake_server = loop.create_future()
server = await loop.create_server(lambda: FstrmServerProtocol(hanshake_server, data_recv), 'localhost', 8000)
hanshake_client = loop.create_future()
transport, client = await loop.create_connection(lambda: FstrmClientProtocol(hanshake_client), 'localhost', 8000)
# check handshake
try:
await asyncio.wait_for(hanshake_server, timeout=5)
except asyncio.TimeoutError:
raise Exception("handshake server failed")
try:
await asyncio.wait_for(hanshake_client, timeout=0.5)
except asyncio.TimeoutError:
raise Exception("handshake client failed")
# ok, the client send some data
data = b"some data..."
client.send_data(data)
# wait data on server side
try:
await asyncio.wait_for( data_recv, timeout=0.5)
except asyncio.TimeoutError:
raise Exception("data expected but failed")
# Shut down server and client
server.close()
transport.close()
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.run_until_complete(run(loop))
```
Raw data
{
"_id": null,
"home_page": "https://github.com/dmachard/python-framestream",
"name": "fstrm",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "framestreams fstrm encoder decoder",
"author": "Denis MACHARD",
"author_email": "d.machard@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/3f/94/29fb167a5c03a583b56d8402e42c0994a3fb010ebd23f857690ca153b989/fstrm-0.6.1.tar.gz",
"platform": "any",
"description": "![Testing](https://github.com/dmachard/python-framestream/workflows/Testing/badge.svg) ![Build](https://github.com/dmachard/python-framestream/workflows/Build/badge.svg) ![Pypi](https://github.com/dmachard/python-framestream/workflows/PyPI/badge.svg)\n\n# Frame Streams implementation in Python\n\nFrame Streams is a lightweight, binary-clean protocol that allows for the transport of arbitrarily encoded data payload sequences with minimal framing overhead.\n\nThis package provides a pure Python implementation based on https://github.com/farsightsec/fstrm/.\n\n## Installation\n\n![python 3.12.x](https://img.shields.io/badge/python%203.12.x-tested-blue) ![python 3.11.x](https://img.shields.io/badge/python%203.11.x-tested-blue) ![python 3.10.x](https://img.shields.io/badge/python%203.10.x-tested-blue) ![python 3.9.x](https://img.shields.io/badge/python%203.9.x-tested-blue) ![python 3.8.x](https://img.shields.io/badge/python%203.8.x-tested-blue)\n\nThis module can be installed from [pypi](https://pypi.org/project/fstrm/) website\n\n```python\npip install fstrm\n```\n\n## Example\n\nThe example shows how to read raw data and decode-it with the fstrsm library.\n\n```python\nimport fstrm\nimport asyncio\n\nclass FstrmServerProtocol(asyncio.Protocol):\n def __init__(self, handshake, data_recv, content_type=b\"plaintext\"):\n self.fstrm = fstrm.FstrmCodec()\n self.content_type = content_type\n self.data_recv = data_recv\n self.handshake = handshake\n self.handshake_accept_done = False\n\n def connection_made(self, transport):\n self.transport = transport\n\n def data_received(self, data):\n if not self.handshake.done():\n if not self.handshake_accept_done:\n if self.fstrm.is_ctrlready(data):\n self.transport.write(self.fstrm.encode_ctrlaccept(self.content_type))\n self.handshake_accept_done = True\n else:\n if self.fstrm.is_ctrlstart(data):\n self.handshake.set_result(True)\n else:\n payload = self.fstrm.is_data(data)\n # do someting with the payload...\n if payload:\n self.data_recv.set_result(payload) \n\nclass FstrmClientProtocol(asyncio.Protocol):\n def __init__(self, handshake, content_type=b\"plaintext\"):\n self.fstrm = fstrm.FstrmCodec()\n self.content_type = content_type\n self.handshake = handshake\n self.transport = None\n\n def connection_made(self, transport):\n self.transport = transport\n self.transport.write(self.fstrm.encode_ctrlready(self.content_type))\n\n def data_received(self, data):\n if not self.handshake.done():\n if self.fstrm.is_ctrlaccept(data):\n self.transport.write(self.fstrm.encode_ctrlstart(self.content_type))\n self.handshake.set_result(True)\n\n def send_data(self, data):\n payload = self.fstrm.encode_data(data)\n self.transport.write(payload)\n\nasync def run(loop):\n # Create server and client\n data_recv = loop.create_future()\n hanshake_server = loop.create_future()\n server = await loop.create_server(lambda: FstrmServerProtocol(hanshake_server, data_recv), 'localhost', 8000)\n\n hanshake_client = loop.create_future()\n transport, client = await loop.create_connection(lambda: FstrmClientProtocol(hanshake_client), 'localhost', 8000)\n\n # check handshake\n try:\n await asyncio.wait_for(hanshake_server, timeout=5)\n except asyncio.TimeoutError:\n raise Exception(\"handshake server failed\")\n\n try:\n await asyncio.wait_for(hanshake_client, timeout=0.5)\n except asyncio.TimeoutError:\n raise Exception(\"handshake client failed\")\n\n # ok, the client send some data\n data = b\"some data...\"\n client.send_data(data)\n\n # wait data on server side\n try:\n await asyncio.wait_for( data_recv, timeout=0.5)\n except asyncio.TimeoutError:\n raise Exception(\"data expected but failed\")\n\n # Shut down server and client\n server.close()\n transport.close()\n\nif __name__ == \"__main__\":\n loop = asyncio.get_event_loop()\n loop.run_until_complete(run(loop))\n```\n",
"bugtrack_url": null,
"license": "",
"summary": "Frame Streams implementation in Python",
"version": "0.6.1",
"project_urls": {
"Homepage": "https://github.com/dmachard/python-framestream"
},
"split_keywords": [
"framestreams",
"fstrm",
"encoder",
"decoder"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "7e77a7f01189ae8c55650798b918172d3cf456cf038bff48f0ab388163df08d2",
"md5": "0c435efe1a7bcb921ee1bb5514997a93",
"sha256": "448376be491ef9c4600b397d6d56d01cf6a4bf58256c8688f93c5efa856216f9"
},
"downloads": -1,
"filename": "fstrm-0.6.1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "0c435efe1a7bcb921ee1bb5514997a93",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 5071,
"upload_time": "2023-12-10T08:13:37",
"upload_time_iso_8601": "2023-12-10T08:13:37.271362Z",
"url": "https://files.pythonhosted.org/packages/7e/77/a7f01189ae8c55650798b918172d3cf456cf038bff48f0ab388163df08d2/fstrm-0.6.1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "3f9429fb167a5c03a583b56d8402e42c0994a3fb010ebd23f857690ca153b989",
"md5": "7ab4b700661e5aa4b5aeaf0e2f014614",
"sha256": "81bcb01ec14a37c2a74712796411b68f93e5afcc679e72315d39365fca671529"
},
"downloads": -1,
"filename": "fstrm-0.6.1.tar.gz",
"has_sig": false,
"md5_digest": "7ab4b700661e5aa4b5aeaf0e2f014614",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 4710,
"upload_time": "2023-12-10T08:13:38",
"upload_time_iso_8601": "2023-12-10T08:13:38.817202Z",
"url": "https://files.pythonhosted.org/packages/3f/94/29fb167a5c03a583b56d8402e42c0994a3fb010ebd23f857690ca153b989/fstrm-0.6.1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-12-10 08:13:38",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "dmachard",
"github_project": "python-framestream",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "fstrm"
}