Skip to content

Commit ab57259

Browse files
author
Fedor Baart
committed
model messages initial version
1 parent 615f13c commit ab57259

File tree

8 files changed

+177
-1
lines changed

8 files changed

+177
-1
lines changed

DESCRIPTION.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Model Message Interface
2+
=======================
3+
4+
This is an implementation of the model message interface for python.
5+

MANIFEST.in

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
include DESCRIPTION.rst
2+
3+
# Include the test suite (FIXME: does not work yet)
4+
# recursive-include tests *
5+
6+
# Explicitly note anything that is in package_data, as Python 2.6 does
7+
# not include these by default
8+
# include sample/*.dat

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
python-mmi
1+
mmi
22
==========
33

44
Model Message Interface. Sending arrays with metadata between processes.

mmi/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
__version__ = '0.1'
2+
import datetime
3+
4+
import numpy as np
5+
import zmq
6+
7+
def send_array(socket, A, flags=0, copy=False, track=False, metadata=None):
8+
"""send a numpy array with metadata"""
9+
md = dict(
10+
dtype=str(A.dtype),
11+
shape=A.shape,
12+
timestamp=datetime.datetime.now().isoformat()
13+
)
14+
if metadata:
15+
md.update(metadata)
16+
if A is None:
17+
# send only json
18+
socket.send_json(md, flags)
19+
else:
20+
# send json, followed by array
21+
socket.send_json(md, flags | zmq.SNDMORE)
22+
# Make a copy if required and pass along the buffer
23+
msg = buffer(np.ascontiguousarray(A))
24+
socket.send(msg, flags, copy=copy, track=track)
25+
return
26+
27+
28+
def recv_array(socket, flags=0, copy=False, track=False):
29+
"""recv a metadata and an optional numpy array"""
30+
md = socket.recv_json(flags=flags)
31+
if socket.getsockopt(zmq.RCVMORE):
32+
msg = socket.recv(flags=flags, copy=copy, track=track)
33+
buf = buffer(msg)
34+
A = np.frombuffer(buf, dtype=md['dtype'])
35+
A.reshape(md['shape'])
36+
else:
37+
# No array expected
38+
A = None
39+
return A, md

setup.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[wheel]
2+
# This flag says that the code is written to work on both Python 2 and Python
3+
# 3. If at all possible, it is good practice to do this. If you cannot, you
4+
# will need to generate wheels for each Python version that you support.
5+
universal=1

setup.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
from setuptools import setup, find_packages
2+
import os
3+
import re
4+
import codecs
5+
# get py3 compatible open
6+
from io import open
7+
8+
here = os.path.abspath(os.path.dirname(__file__))
9+
10+
# Read the version number from a source file.
11+
# Code taken from pip's setup.py
12+
def find_version(*file_paths):
13+
# Open in Latin-1 so that we avoid encoding errors.
14+
# Use codecs.open for Python 2 compatibility
15+
with codecs.open(os.path.join(here, *file_paths), 'r', 'latin1') as f:
16+
version_file = f.read()
17+
18+
# The version line must have the form
19+
# __version__ = 'ver'
20+
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
21+
version_file, re.M)
22+
if version_match:
23+
return version_match.group(1)
24+
raise RuntimeError("Unable to find version string.")
25+
26+
27+
# Get the long description from the relevant file
28+
with open('DESCRIPTION.rst', encoding='utf-8') as f:
29+
long_description = f.read()
30+
31+
setup(
32+
name="mmi",
33+
version=find_version('mmi', '__init__.py'),
34+
description="Model Message Interface",
35+
long_description=long_description,
36+
37+
# The project URL.
38+
url='http://github.com/pfmoore/sampleproject',
39+
40+
# Author details
41+
author='Fedor Baart',
42+
author_email='[email protected]',
43+
44+
# Choose your license
45+
license='GPLv3+',
46+
47+
classifiers=[
48+
# How mature is this project? Common values are
49+
# 3 - Alpha
50+
# 4 - Beta
51+
# 5 - Production/Stable
52+
'Development Status :: 3 - Alpha',
53+
54+
# Indicate who your project is intended for
55+
'Intended Audience :: Science/Research',
56+
'Intended Audience :: Developers',
57+
'Topic :: Scientific/Engineering',
58+
'Topic :: System :: Distributed Computing',
59+
60+
# Pick your license as you wish (should match "license" above)
61+
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)"
62+
63+
# Specify the Python versions you support here. In particular, ensure
64+
# that you indicate whether you support Python 2, Python 3 or both.
65+
'Programming Language :: Python :: 2',
66+
'Programming Language :: Python :: 2.7',
67+
'Programming Language :: Python :: 3',
68+
'Programming Language :: Python :: 3.1',
69+
'Programming Language :: Python :: 3.2',
70+
'Programming Language :: Python :: 3.3',
71+
],
72+
73+
# What does your project relate to?
74+
keywords='array messages model',
75+
76+
# You can just specify the packages manually here if your project is
77+
# simple. Or you can use find_packages.
78+
packages=find_packages(exclude=["contrib", "docs", "tests*"]),
79+
# If there are data files included in your packages, specify them here.
80+
package_data={
81+
# 'sample': ['*.dat'],
82+
},
83+
84+
install_requires = [
85+
'numpy',
86+
'zmq'
87+
],
88+
# To provide executable scripts, use entry points in preference to the
89+
# "scripts" keyword. Entry points provide cross-platform support and allow
90+
# pip to create the appropriate form of executable for the target platform.
91+
entry_points={
92+
'console_scripts': [
93+
# 'runner=runner:main',
94+
],
95+
},
96+
)

tests/__init__.py

Whitespace-only changes.

tests/test_simple.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import unittest
2+
import mmi
3+
4+
import numpy as np
5+
import numpy.testing
6+
import zmq
7+
8+
9+
# global context
10+
ctx = zmq.Context()
11+
class TestRecv(unittest.TestCase):
12+
def test_sndrcv(self):
13+
A = np.array([1,2,3])
14+
req = ctx.socket(zmq.REQ)
15+
req.connect('tcp://localhost:9002')
16+
rep = ctx.socket(zmq.REP)
17+
rep.bind('tcp://*:9002')
18+
mmi.send_array(req, A)
19+
B, metadata = mmi.recv_array(rep)
20+
numpy.testing.assert_array_equal(A, B)
21+
22+
23+

0 commit comments

Comments
 (0)