python-osc 1.8.0__tar.gz → 1.8.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {python-osc-1.8.0 → python-osc-1.8.2}/MANIFEST.in +1 -0
- python-osc-1.8.2/PKG-INFO +202 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/README.rst +6 -6
- python-osc-1.8.2/pyproject.toml +21 -0
- python-osc-1.8.2/python_osc.egg-info/PKG-INFO +202 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/python_osc.egg-info/SOURCES.txt +2 -1
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/dispatcher.py +10 -11
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_bundle.py +6 -8
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_bundle_builder.py +3 -1
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_message.py +7 -4
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_message_builder.py +21 -18
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_packet.py +5 -5
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/osc_server.py +12 -7
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/parsing/ntp.py +5 -4
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/parsing/osc_types.py +9 -5
- python-osc-1.8.2/pythonosc/test/parsing/__init__.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_message.py +8 -6
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_message_builder.py +1 -1
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_server.py +3 -3
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/udp_client.py +12 -9
- python-osc-1.8.2/setup.cfg +18 -0
- python-osc-1.8.0/PKG-INFO +0 -178
- python-osc-1.8.0/python_osc.egg-info/PKG-INFO +0 -178
- python-osc-1.8.0/setup.cfg +0 -7
- python-osc-1.8.0/setup.py +0 -41
- {python-osc-1.8.0 → python-osc-1.8.2}/LICENSE.txt +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/python_osc.egg-info/dependency_links.txt +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/python_osc.egg-info/top_level.txt +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/__init__.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/parsing/__init__.py +0 -0
- /python-osc-1.8.0/pythonosc/test/__init__.py → /python-osc-1.8.2/pythonosc/py.typed +0 -0
- {python-osc-1.8.0/pythonosc/test/parsing → python-osc-1.8.2/pythonosc/test}/__init__.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/parsing/test_ntp.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/parsing/test_osc_types.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_dispatcher.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_bundle.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_bundle_builder.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_osc_packet.py +0 -0
- {python-osc-1.8.0 → python-osc-1.8.2}/pythonosc/test/test_udp_client.py +0 -0
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: python-osc
|
|
3
|
+
Version: 1.8.2
|
|
4
|
+
Summary: Open Sound Control server and client implementations in pure Python
|
|
5
|
+
Author-email: attwad <tmusoft@gmail.com>
|
|
6
|
+
License: This is free and unencumbered software released into the public domain.
|
|
7
|
+
|
|
8
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
9
|
+
distribute this software, either in source code form or as a compiled
|
|
10
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
11
|
+
means.
|
|
12
|
+
|
|
13
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
14
|
+
of this software dedicate any and all copyright interest in the
|
|
15
|
+
software to the public domain. We make this dedication for the benefit
|
|
16
|
+
of the public at large and to the detriment of our heirs and
|
|
17
|
+
successors. We intend this dedication to be an overt act of
|
|
18
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
19
|
+
software under copyright law.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
22
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
23
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
24
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
25
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
26
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
27
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
28
|
+
|
|
29
|
+
For more information, please refer to <http://unlicense.org/>
|
|
30
|
+
|
|
31
|
+
Project-URL: Repository, https://github.com/attwad/python-osc
|
|
32
|
+
Keywords: osc,sound,midi,music
|
|
33
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: Freely Distributable
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
38
|
+
Classifier: Topic :: System :: Networking
|
|
39
|
+
Requires-Python: >=3.7
|
|
40
|
+
Description-Content-Type: text/x-rst
|
|
41
|
+
License-File: LICENSE.txt
|
|
42
|
+
|
|
43
|
+
==========
|
|
44
|
+
python-osc
|
|
45
|
+
==========
|
|
46
|
+
|
|
47
|
+
Open Sound Control server and client implementations in **pure python**.
|
|
48
|
+
|
|
49
|
+
.. image:: https://github.com/attwad/python-osc/actions/workflows/python-test.yml/badge.svg
|
|
50
|
+
:target: https://github.com/attwad/python-osc/actions/workflows/python-test.yml
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
Current status
|
|
54
|
+
==============
|
|
55
|
+
|
|
56
|
+
This library was developed following the
|
|
57
|
+
`OpenSoundControl Specification 1.0 <https://opensoundcontrol.stanford.edu/spec-1_0.html>`_
|
|
58
|
+
and is currently in a stable state.
|
|
59
|
+
|
|
60
|
+
Features
|
|
61
|
+
========
|
|
62
|
+
|
|
63
|
+
* UDP blocking/threading/forking/asyncio server implementations
|
|
64
|
+
* UDP client
|
|
65
|
+
* int, int64, float, string, double, MIDI, timestamps, blob, nil OSC arguments
|
|
66
|
+
* simple OSC address<->callback matching system
|
|
67
|
+
* extensive unit test coverage
|
|
68
|
+
* basic client and server examples
|
|
69
|
+
|
|
70
|
+
Documentation
|
|
71
|
+
=============
|
|
72
|
+
|
|
73
|
+
Available at https://python-osc.readthedocs.io/.
|
|
74
|
+
|
|
75
|
+
Installation
|
|
76
|
+
============
|
|
77
|
+
|
|
78
|
+
python-osc is a pure python library that has no external dependencies,
|
|
79
|
+
to install it just use pip (prefered):
|
|
80
|
+
|
|
81
|
+
.. image:: https://img.shields.io/pypi/v/python-osc.svg
|
|
82
|
+
:target: https://pypi.python.org/pypi/python-osc
|
|
83
|
+
|
|
84
|
+
.. code-block:: bash
|
|
85
|
+
|
|
86
|
+
$ pip install python-osc
|
|
87
|
+
|
|
88
|
+
or from the raw sources for the development version:
|
|
89
|
+
|
|
90
|
+
.. code-block:: bash
|
|
91
|
+
|
|
92
|
+
$ python setup.py test
|
|
93
|
+
$ python setup.py install
|
|
94
|
+
|
|
95
|
+
Examples
|
|
96
|
+
========
|
|
97
|
+
|
|
98
|
+
Simple client
|
|
99
|
+
-------------
|
|
100
|
+
|
|
101
|
+
.. code-block:: python
|
|
102
|
+
|
|
103
|
+
"""Small example OSC client
|
|
104
|
+
|
|
105
|
+
This program sends 10 random values between 0.0 and 1.0 to the /filter address,
|
|
106
|
+
waiting for 1 seconds between each value.
|
|
107
|
+
"""
|
|
108
|
+
import argparse
|
|
109
|
+
import random
|
|
110
|
+
import time
|
|
111
|
+
|
|
112
|
+
from pythonosc import udp_client
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
parser = argparse.ArgumentParser()
|
|
117
|
+
parser.add_argument("--ip", default="127.0.0.1",
|
|
118
|
+
help="The ip of the OSC server")
|
|
119
|
+
parser.add_argument("--port", type=int, default=5005,
|
|
120
|
+
help="The port the OSC server is listening on")
|
|
121
|
+
args = parser.parse_args()
|
|
122
|
+
|
|
123
|
+
client = udp_client.SimpleUDPClient(args.ip, args.port)
|
|
124
|
+
|
|
125
|
+
for x in range(10):
|
|
126
|
+
client.send_message("/filter", random.random())
|
|
127
|
+
time.sleep(1)
|
|
128
|
+
|
|
129
|
+
Simple server
|
|
130
|
+
-------------
|
|
131
|
+
|
|
132
|
+
.. code-block:: python
|
|
133
|
+
|
|
134
|
+
"""Small example OSC server
|
|
135
|
+
|
|
136
|
+
This program listens to several addresses, and prints some information about
|
|
137
|
+
received packets.
|
|
138
|
+
"""
|
|
139
|
+
import argparse
|
|
140
|
+
import math
|
|
141
|
+
|
|
142
|
+
from pythonosc.dispatcher import Dispatcher
|
|
143
|
+
from pythonosc import osc_server
|
|
144
|
+
|
|
145
|
+
def print_volume_handler(unused_addr, args, volume):
|
|
146
|
+
print("[{0}] ~ {1}".format(args[0], volume))
|
|
147
|
+
|
|
148
|
+
def print_compute_handler(unused_addr, args, volume):
|
|
149
|
+
try:
|
|
150
|
+
print("[{0}] ~ {1}".format(args[0], args[1](volume)))
|
|
151
|
+
except ValueError: pass
|
|
152
|
+
|
|
153
|
+
if __name__ == "__main__":
|
|
154
|
+
parser = argparse.ArgumentParser()
|
|
155
|
+
parser.add_argument("--ip",
|
|
156
|
+
default="127.0.0.1", help="The ip to listen on")
|
|
157
|
+
parser.add_argument("--port",
|
|
158
|
+
type=int, default=5005, help="The port to listen on")
|
|
159
|
+
args = parser.parse_args()
|
|
160
|
+
|
|
161
|
+
dispatcher = Dispatcher()
|
|
162
|
+
dispatcher.map("/filter", print)
|
|
163
|
+
dispatcher.map("/volume", print_volume_handler, "Volume")
|
|
164
|
+
dispatcher.map("/logvolume", print_compute_handler, "Log volume", math.log)
|
|
165
|
+
|
|
166
|
+
server = osc_server.ThreadingOSCUDPServer(
|
|
167
|
+
(args.ip, args.port), dispatcher)
|
|
168
|
+
print("Serving on {}".format(server.server_address))
|
|
169
|
+
server.serve_forever()
|
|
170
|
+
|
|
171
|
+
Building bundles
|
|
172
|
+
----------------
|
|
173
|
+
|
|
174
|
+
.. code-block:: python
|
|
175
|
+
|
|
176
|
+
from pythonosc import osc_bundle_builder
|
|
177
|
+
from pythonosc import osc_message_builder
|
|
178
|
+
|
|
179
|
+
bundle = osc_bundle_builder.OscBundleBuilder(
|
|
180
|
+
osc_bundle_builder.IMMEDIATELY)
|
|
181
|
+
msg = osc_message_builder.OscMessageBuilder(address="/SYNC")
|
|
182
|
+
msg.add_arg(4.0)
|
|
183
|
+
# Add 4 messages in the bundle, each with more arguments.
|
|
184
|
+
bundle.add_content(msg.build())
|
|
185
|
+
msg.add_arg(2)
|
|
186
|
+
bundle.add_content(msg.build())
|
|
187
|
+
msg.add_arg("value")
|
|
188
|
+
bundle.add_content(msg.build())
|
|
189
|
+
msg.add_arg(b"\x01\x02\x03")
|
|
190
|
+
bundle.add_content(msg.build())
|
|
191
|
+
|
|
192
|
+
sub_bundle = bundle.build()
|
|
193
|
+
# Now add the same bundle inside itself.
|
|
194
|
+
bundle.add_content(sub_bundle)
|
|
195
|
+
# The bundle has 5 elements in total now.
|
|
196
|
+
|
|
197
|
+
bundle = bundle.build()
|
|
198
|
+
# You can now send it via a client as described in other examples.
|
|
199
|
+
|
|
200
|
+
License?
|
|
201
|
+
========
|
|
202
|
+
Unlicensed, do what you want with it. (http://unlicense.org)
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
python-osc
|
|
3
3
|
==========
|
|
4
4
|
|
|
5
|
-
Open Sound Control server and client implementations in **pure python
|
|
5
|
+
Open Sound Control server and client implementations in **pure python**.
|
|
6
6
|
|
|
7
7
|
.. image:: https://github.com/attwad/python-osc/actions/workflows/python-test.yml/badge.svg
|
|
8
8
|
:target: https://github.com/attwad/python-osc/actions/workflows/python-test.yml
|
|
@@ -11,8 +11,8 @@ Open Sound Control server and client implementations in **pure python** (3.5+).
|
|
|
11
11
|
Current status
|
|
12
12
|
==============
|
|
13
13
|
|
|
14
|
-
This library was
|
|
15
|
-
|
|
14
|
+
This library was developed following the
|
|
15
|
+
`OpenSoundControl Specification 1.0 <https://opensoundcontrol.stanford.edu/spec-1_0.html>`_
|
|
16
16
|
and is currently in a stable state.
|
|
17
17
|
|
|
18
18
|
Features
|
|
@@ -20,7 +20,7 @@ Features
|
|
|
20
20
|
|
|
21
21
|
* UDP blocking/threading/forking/asyncio server implementations
|
|
22
22
|
* UDP client
|
|
23
|
-
* int, int64, float, string, double, MIDI, timestamps, blob OSC arguments
|
|
23
|
+
* int, int64, float, string, double, MIDI, timestamps, blob, nil OSC arguments
|
|
24
24
|
* simple OSC address<->callback matching system
|
|
25
25
|
* extensive unit test coverage
|
|
26
26
|
* basic client and server examples
|
|
@@ -97,7 +97,7 @@ Simple server
|
|
|
97
97
|
import argparse
|
|
98
98
|
import math
|
|
99
99
|
|
|
100
|
-
from pythonosc import
|
|
100
|
+
from pythonosc.dispatcher import Dispatcher
|
|
101
101
|
from pythonosc import osc_server
|
|
102
102
|
|
|
103
103
|
def print_volume_handler(unused_addr, args, volume):
|
|
@@ -116,7 +116,7 @@ Simple server
|
|
|
116
116
|
type=int, default=5005, help="The port to listen on")
|
|
117
117
|
args = parser.parse_args()
|
|
118
118
|
|
|
119
|
-
dispatcher =
|
|
119
|
+
dispatcher = Dispatcher()
|
|
120
120
|
dispatcher.map("/filter", print)
|
|
121
121
|
dispatcher.map("/volume", print_volume_handler, "Volume")
|
|
122
122
|
dispatcher.map("/logvolume", print_compute_handler, "Log volume", math.log)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "python-osc"
|
|
3
|
+
version="1.8.2"
|
|
4
|
+
description="Open Sound Control server and client implementations in pure Python"
|
|
5
|
+
readme="README.rst"
|
|
6
|
+
requires-python=">=3.7"
|
|
7
|
+
license = {file = "LICENSE.txt"}
|
|
8
|
+
authors = [
|
|
9
|
+
{name = "attwad", email = "tmusoft@gmail.com"},
|
|
10
|
+
]
|
|
11
|
+
keywords = ["osc", "sound", "midi", "music"]
|
|
12
|
+
classifiers=[
|
|
13
|
+
'Development Status :: 5 - Production/Stable',
|
|
14
|
+
'Intended Audience :: Developers',
|
|
15
|
+
'License :: Freely Distributable',
|
|
16
|
+
'Programming Language :: Python :: 3',
|
|
17
|
+
'Topic :: Multimedia :: Sound/Audio',
|
|
18
|
+
'Topic :: System :: Networking',
|
|
19
|
+
]
|
|
20
|
+
[project.urls]
|
|
21
|
+
Repository = "https://github.com/attwad/python-osc"
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: python-osc
|
|
3
|
+
Version: 1.8.2
|
|
4
|
+
Summary: Open Sound Control server and client implementations in pure Python
|
|
5
|
+
Author-email: attwad <tmusoft@gmail.com>
|
|
6
|
+
License: This is free and unencumbered software released into the public domain.
|
|
7
|
+
|
|
8
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
9
|
+
distribute this software, either in source code form or as a compiled
|
|
10
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
11
|
+
means.
|
|
12
|
+
|
|
13
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
14
|
+
of this software dedicate any and all copyright interest in the
|
|
15
|
+
software to the public domain. We make this dedication for the benefit
|
|
16
|
+
of the public at large and to the detriment of our heirs and
|
|
17
|
+
successors. We intend this dedication to be an overt act of
|
|
18
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
19
|
+
software under copyright law.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
22
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
23
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
24
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
25
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
26
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
27
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
28
|
+
|
|
29
|
+
For more information, please refer to <http://unlicense.org/>
|
|
30
|
+
|
|
31
|
+
Project-URL: Repository, https://github.com/attwad/python-osc
|
|
32
|
+
Keywords: osc,sound,midi,music
|
|
33
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
34
|
+
Classifier: Intended Audience :: Developers
|
|
35
|
+
Classifier: License :: Freely Distributable
|
|
36
|
+
Classifier: Programming Language :: Python :: 3
|
|
37
|
+
Classifier: Topic :: Multimedia :: Sound/Audio
|
|
38
|
+
Classifier: Topic :: System :: Networking
|
|
39
|
+
Requires-Python: >=3.7
|
|
40
|
+
Description-Content-Type: text/x-rst
|
|
41
|
+
License-File: LICENSE.txt
|
|
42
|
+
|
|
43
|
+
==========
|
|
44
|
+
python-osc
|
|
45
|
+
==========
|
|
46
|
+
|
|
47
|
+
Open Sound Control server and client implementations in **pure python**.
|
|
48
|
+
|
|
49
|
+
.. image:: https://github.com/attwad/python-osc/actions/workflows/python-test.yml/badge.svg
|
|
50
|
+
:target: https://github.com/attwad/python-osc/actions/workflows/python-test.yml
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
Current status
|
|
54
|
+
==============
|
|
55
|
+
|
|
56
|
+
This library was developed following the
|
|
57
|
+
`OpenSoundControl Specification 1.0 <https://opensoundcontrol.stanford.edu/spec-1_0.html>`_
|
|
58
|
+
and is currently in a stable state.
|
|
59
|
+
|
|
60
|
+
Features
|
|
61
|
+
========
|
|
62
|
+
|
|
63
|
+
* UDP blocking/threading/forking/asyncio server implementations
|
|
64
|
+
* UDP client
|
|
65
|
+
* int, int64, float, string, double, MIDI, timestamps, blob, nil OSC arguments
|
|
66
|
+
* simple OSC address<->callback matching system
|
|
67
|
+
* extensive unit test coverage
|
|
68
|
+
* basic client and server examples
|
|
69
|
+
|
|
70
|
+
Documentation
|
|
71
|
+
=============
|
|
72
|
+
|
|
73
|
+
Available at https://python-osc.readthedocs.io/.
|
|
74
|
+
|
|
75
|
+
Installation
|
|
76
|
+
============
|
|
77
|
+
|
|
78
|
+
python-osc is a pure python library that has no external dependencies,
|
|
79
|
+
to install it just use pip (prefered):
|
|
80
|
+
|
|
81
|
+
.. image:: https://img.shields.io/pypi/v/python-osc.svg
|
|
82
|
+
:target: https://pypi.python.org/pypi/python-osc
|
|
83
|
+
|
|
84
|
+
.. code-block:: bash
|
|
85
|
+
|
|
86
|
+
$ pip install python-osc
|
|
87
|
+
|
|
88
|
+
or from the raw sources for the development version:
|
|
89
|
+
|
|
90
|
+
.. code-block:: bash
|
|
91
|
+
|
|
92
|
+
$ python setup.py test
|
|
93
|
+
$ python setup.py install
|
|
94
|
+
|
|
95
|
+
Examples
|
|
96
|
+
========
|
|
97
|
+
|
|
98
|
+
Simple client
|
|
99
|
+
-------------
|
|
100
|
+
|
|
101
|
+
.. code-block:: python
|
|
102
|
+
|
|
103
|
+
"""Small example OSC client
|
|
104
|
+
|
|
105
|
+
This program sends 10 random values between 0.0 and 1.0 to the /filter address,
|
|
106
|
+
waiting for 1 seconds between each value.
|
|
107
|
+
"""
|
|
108
|
+
import argparse
|
|
109
|
+
import random
|
|
110
|
+
import time
|
|
111
|
+
|
|
112
|
+
from pythonosc import udp_client
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
if __name__ == "__main__":
|
|
116
|
+
parser = argparse.ArgumentParser()
|
|
117
|
+
parser.add_argument("--ip", default="127.0.0.1",
|
|
118
|
+
help="The ip of the OSC server")
|
|
119
|
+
parser.add_argument("--port", type=int, default=5005,
|
|
120
|
+
help="The port the OSC server is listening on")
|
|
121
|
+
args = parser.parse_args()
|
|
122
|
+
|
|
123
|
+
client = udp_client.SimpleUDPClient(args.ip, args.port)
|
|
124
|
+
|
|
125
|
+
for x in range(10):
|
|
126
|
+
client.send_message("/filter", random.random())
|
|
127
|
+
time.sleep(1)
|
|
128
|
+
|
|
129
|
+
Simple server
|
|
130
|
+
-------------
|
|
131
|
+
|
|
132
|
+
.. code-block:: python
|
|
133
|
+
|
|
134
|
+
"""Small example OSC server
|
|
135
|
+
|
|
136
|
+
This program listens to several addresses, and prints some information about
|
|
137
|
+
received packets.
|
|
138
|
+
"""
|
|
139
|
+
import argparse
|
|
140
|
+
import math
|
|
141
|
+
|
|
142
|
+
from pythonosc.dispatcher import Dispatcher
|
|
143
|
+
from pythonosc import osc_server
|
|
144
|
+
|
|
145
|
+
def print_volume_handler(unused_addr, args, volume):
|
|
146
|
+
print("[{0}] ~ {1}".format(args[0], volume))
|
|
147
|
+
|
|
148
|
+
def print_compute_handler(unused_addr, args, volume):
|
|
149
|
+
try:
|
|
150
|
+
print("[{0}] ~ {1}".format(args[0], args[1](volume)))
|
|
151
|
+
except ValueError: pass
|
|
152
|
+
|
|
153
|
+
if __name__ == "__main__":
|
|
154
|
+
parser = argparse.ArgumentParser()
|
|
155
|
+
parser.add_argument("--ip",
|
|
156
|
+
default="127.0.0.1", help="The ip to listen on")
|
|
157
|
+
parser.add_argument("--port",
|
|
158
|
+
type=int, default=5005, help="The port to listen on")
|
|
159
|
+
args = parser.parse_args()
|
|
160
|
+
|
|
161
|
+
dispatcher = Dispatcher()
|
|
162
|
+
dispatcher.map("/filter", print)
|
|
163
|
+
dispatcher.map("/volume", print_volume_handler, "Volume")
|
|
164
|
+
dispatcher.map("/logvolume", print_compute_handler, "Log volume", math.log)
|
|
165
|
+
|
|
166
|
+
server = osc_server.ThreadingOSCUDPServer(
|
|
167
|
+
(args.ip, args.port), dispatcher)
|
|
168
|
+
print("Serving on {}".format(server.server_address))
|
|
169
|
+
server.serve_forever()
|
|
170
|
+
|
|
171
|
+
Building bundles
|
|
172
|
+
----------------
|
|
173
|
+
|
|
174
|
+
.. code-block:: python
|
|
175
|
+
|
|
176
|
+
from pythonosc import osc_bundle_builder
|
|
177
|
+
from pythonosc import osc_message_builder
|
|
178
|
+
|
|
179
|
+
bundle = osc_bundle_builder.OscBundleBuilder(
|
|
180
|
+
osc_bundle_builder.IMMEDIATELY)
|
|
181
|
+
msg = osc_message_builder.OscMessageBuilder(address="/SYNC")
|
|
182
|
+
msg.add_arg(4.0)
|
|
183
|
+
# Add 4 messages in the bundle, each with more arguments.
|
|
184
|
+
bundle.add_content(msg.build())
|
|
185
|
+
msg.add_arg(2)
|
|
186
|
+
bundle.add_content(msg.build())
|
|
187
|
+
msg.add_arg("value")
|
|
188
|
+
bundle.add_content(msg.build())
|
|
189
|
+
msg.add_arg(b"\x01\x02\x03")
|
|
190
|
+
bundle.add_content(msg.build())
|
|
191
|
+
|
|
192
|
+
sub_bundle = bundle.build()
|
|
193
|
+
# Now add the same bundle inside itself.
|
|
194
|
+
bundle.add_content(sub_bundle)
|
|
195
|
+
# The bundle has 5 elements in total now.
|
|
196
|
+
|
|
197
|
+
bundle = bundle.build()
|
|
198
|
+
# You can now send it via a client as described in other examples.
|
|
199
|
+
|
|
200
|
+
License?
|
|
201
|
+
========
|
|
202
|
+
Unlicensed, do what you want with it. (http://unlicense.org)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
LICENSE.txt
|
|
2
2
|
MANIFEST.in
|
|
3
3
|
README.rst
|
|
4
|
+
pyproject.toml
|
|
4
5
|
setup.cfg
|
|
5
|
-
setup.py
|
|
6
6
|
python_osc.egg-info/PKG-INFO
|
|
7
7
|
python_osc.egg-info/SOURCES.txt
|
|
8
8
|
python_osc.egg-info/dependency_links.txt
|
|
@@ -15,6 +15,7 @@ pythonosc/osc_message.py
|
|
|
15
15
|
pythonosc/osc_message_builder.py
|
|
16
16
|
pythonosc/osc_packet.py
|
|
17
17
|
pythonosc/osc_server.py
|
|
18
|
+
pythonosc/py.typed
|
|
18
19
|
pythonosc/udp_client.py
|
|
19
20
|
pythonosc/parsing/__init__.py
|
|
20
21
|
pythonosc/parsing/ntp.py
|
|
@@ -6,8 +6,7 @@ import logging
|
|
|
6
6
|
import re
|
|
7
7
|
import time
|
|
8
8
|
from pythonosc import osc_packet
|
|
9
|
-
from typing import overload, List, Union, Any, Generator, Tuple
|
|
10
|
-
from types import FunctionType
|
|
9
|
+
from typing import overload, List, Union, Any, Generator, Tuple, Callable, Optional, DefaultDict
|
|
11
10
|
from pythonosc.osc_message import OscMessage
|
|
12
11
|
|
|
13
12
|
|
|
@@ -19,7 +18,7 @@ class Handler(object):
|
|
|
19
18
|
message if any were passed.
|
|
20
19
|
"""
|
|
21
20
|
|
|
22
|
-
def __init__(self, _callback:
|
|
21
|
+
def __init__(self, _callback: Callable, _args: Union[Any, List[Any]],
|
|
23
22
|
_needs_reply_address: bool = False) -> None:
|
|
24
23
|
"""
|
|
25
24
|
Args:
|
|
@@ -32,13 +31,13 @@ class Handler(object):
|
|
|
32
31
|
self.needs_reply_address = _needs_reply_address
|
|
33
32
|
|
|
34
33
|
# needed for test module
|
|
35
|
-
def __eq__(self, other) -> bool:
|
|
34
|
+
def __eq__(self, other: Any) -> bool:
|
|
36
35
|
return (type(self) == type(other) and
|
|
37
36
|
self.callback == other.callback and
|
|
38
37
|
self.args == other.args and
|
|
39
38
|
self.needs_reply_address == other.needs_reply_address)
|
|
40
39
|
|
|
41
|
-
def invoke(self, client_address: str, message: OscMessage) -> None:
|
|
40
|
+
def invoke(self, client_address: Tuple[str, int], message: OscMessage) -> None:
|
|
42
41
|
"""Invokes the associated callback function
|
|
43
42
|
|
|
44
43
|
Args:
|
|
@@ -64,10 +63,10 @@ class Dispatcher(object):
|
|
|
64
63
|
"""
|
|
65
64
|
|
|
66
65
|
def __init__(self) -> None:
|
|
67
|
-
self._map = collections.defaultdict(list)
|
|
68
|
-
self._default_handler = None
|
|
66
|
+
self._map = collections.defaultdict(list) # type: DefaultDict[str, List[Handler]]
|
|
67
|
+
self._default_handler = None # type: Optional[Handler]
|
|
69
68
|
|
|
70
|
-
def map(self, address: str, handler:
|
|
69
|
+
def map(self, address: str, handler: Callable, *args: Union[Any, List[Any]],
|
|
71
70
|
needs_reply_address: bool = False) -> Handler:
|
|
72
71
|
"""Map an address to a handler
|
|
73
72
|
|
|
@@ -108,7 +107,7 @@ class Dispatcher(object):
|
|
|
108
107
|
pass
|
|
109
108
|
|
|
110
109
|
@overload
|
|
111
|
-
def unmap(self, address: str, handler:
|
|
110
|
+
def unmap(self, address: str, handler: Callable, *args: Union[Any, List[Any]],
|
|
112
111
|
needs_reply_address: bool = False) -> None:
|
|
113
112
|
"""Remove an already mapped handler from an address
|
|
114
113
|
|
|
@@ -133,7 +132,7 @@ class Dispatcher(object):
|
|
|
133
132
|
if str(e) == "list.remove(x): x not in list":
|
|
134
133
|
raise ValueError("Address '%s' doesn't have handler '%s' mapped to it" % (address, handler)) from e
|
|
135
134
|
|
|
136
|
-
def handlers_for_address(self, address_pattern: str) -> Generator[
|
|
135
|
+
def handlers_for_address(self, address_pattern: str) -> Generator[Handler, None, None]:
|
|
137
136
|
"""Yields handlers matching an address
|
|
138
137
|
|
|
139
138
|
|
|
@@ -195,7 +194,7 @@ class Dispatcher(object):
|
|
|
195
194
|
except osc_packet.ParseError:
|
|
196
195
|
pass
|
|
197
196
|
|
|
198
|
-
def set_default_handler(self, handler:
|
|
197
|
+
def set_default_handler(self, handler: Callable, needs_reply_address: bool = False) -> None:
|
|
199
198
|
"""Sets the default handler
|
|
200
199
|
|
|
201
200
|
The default handler is invoked every time no other handler is mapped to an address.
|
|
@@ -3,7 +3,7 @@ import logging
|
|
|
3
3
|
from pythonosc import osc_message
|
|
4
4
|
from pythonosc.parsing import osc_types
|
|
5
5
|
|
|
6
|
-
from typing import Any, Iterator
|
|
6
|
+
from typing import Any, Iterator, List, Union
|
|
7
7
|
|
|
8
8
|
_BUNDLE_PREFIX = b"#bundle\x00"
|
|
9
9
|
|
|
@@ -37,10 +37,8 @@ class OscBundle(object):
|
|
|
37
37
|
# Get the contents as a list of OscBundle and OscMessage.
|
|
38
38
|
self._contents = self._parse_contents(index)
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def _parse_contents(self, index: int) -> Any:
|
|
43
|
-
contents = []
|
|
40
|
+
def _parse_contents(self, index: int) -> List[Union['OscBundle', osc_message.OscMessage]]:
|
|
41
|
+
contents = [] # type: List[Union[OscBundle, osc_message.OscMessage]]
|
|
44
42
|
|
|
45
43
|
try:
|
|
46
44
|
# An OSC Bundle Element consists of its size and its contents.
|
|
@@ -61,7 +59,7 @@ class OscBundle(object):
|
|
|
61
59
|
contents.append(osc_message.OscMessage(content_dgram))
|
|
62
60
|
else:
|
|
63
61
|
logging.warning(
|
|
64
|
-
"Could not identify content type of dgram %
|
|
62
|
+
"Could not identify content type of dgram %r" % content_dgram)
|
|
65
63
|
except (osc_types.ParseError, osc_message.ParseError, IndexError) as e:
|
|
66
64
|
raise ParseError("Could not parse a content datagram: %s" % e)
|
|
67
65
|
|
|
@@ -73,7 +71,7 @@ class OscBundle(object):
|
|
|
73
71
|
return dgram.startswith(_BUNDLE_PREFIX)
|
|
74
72
|
|
|
75
73
|
@property
|
|
76
|
-
def timestamp(self) ->
|
|
74
|
+
def timestamp(self) -> float:
|
|
77
75
|
"""Returns the timestamp associated with this bundle."""
|
|
78
76
|
return self._timestamp
|
|
79
77
|
|
|
@@ -92,7 +90,7 @@ class OscBundle(object):
|
|
|
92
90
|
"""Returns the datagram from which this bundle was built."""
|
|
93
91
|
return self._dgram
|
|
94
92
|
|
|
95
|
-
def content(self, index) -> Any:
|
|
93
|
+
def content(self, index: int) -> Any:
|
|
96
94
|
"""Returns the bundle's content 0-indexed."""
|
|
97
95
|
return self._contents[index]
|
|
98
96
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Build OSC bundles for client applications."""
|
|
2
2
|
|
|
3
|
+
from typing import List
|
|
4
|
+
|
|
3
5
|
from pythonosc import osc_bundle
|
|
4
6
|
from pythonosc import osc_message
|
|
5
7
|
from pythonosc.parsing import osc_types
|
|
@@ -23,7 +25,7 @@ class OscBundleBuilder(object):
|
|
|
23
25
|
seconds since the epoch in UTC or IMMEDIATELY.
|
|
24
26
|
"""
|
|
25
27
|
self._timestamp = timestamp
|
|
26
|
-
self._contents = []
|
|
28
|
+
self._contents = [] # type: List[osc_bundle.OscBundle]
|
|
27
29
|
|
|
28
30
|
def add_content(self, content: osc_bundle.OscBundle) -> None:
|
|
29
31
|
"""Add a new content to this bundle.
|
|
@@ -19,7 +19,7 @@ class OscMessage(object):
|
|
|
19
19
|
|
|
20
20
|
def __init__(self, dgram: bytes) -> None:
|
|
21
21
|
self._dgram = dgram
|
|
22
|
-
self._parameters = []
|
|
22
|
+
self._parameters = [] # type: List[Any]
|
|
23
23
|
self._parse_datagram()
|
|
24
24
|
|
|
25
25
|
def _parse_datagram(self) -> None:
|
|
@@ -34,10 +34,11 @@ class OscMessage(object):
|
|
|
34
34
|
if type_tag.startswith(','):
|
|
35
35
|
type_tag = type_tag[1:]
|
|
36
36
|
|
|
37
|
-
params = []
|
|
37
|
+
params = [] # type: List[Any]
|
|
38
38
|
param_stack = [params]
|
|
39
39
|
# Parse each parameter given its type.
|
|
40
40
|
for param in type_tag:
|
|
41
|
+
val = NotImplemented # type: Any
|
|
41
42
|
if param == "i": # Integer.
|
|
42
43
|
val, index = osc_types.get_int(self._dgram, index)
|
|
43
44
|
elif param == "h": # Int64.
|
|
@@ -60,8 +61,10 @@ class OscMessage(object):
|
|
|
60
61
|
val = True
|
|
61
62
|
elif param == "F": # False.
|
|
62
63
|
val = False
|
|
64
|
+
elif param == "N": # Nil.
|
|
65
|
+
val = None
|
|
63
66
|
elif param == "[": # Array start.
|
|
64
|
-
array = []
|
|
67
|
+
array = [] # type: List[Any]
|
|
65
68
|
param_stack[-1].append(array)
|
|
66
69
|
param_stack.append(array)
|
|
67
70
|
elif param == "]": # Array stop.
|
|
@@ -105,6 +108,6 @@ class OscMessage(object):
|
|
|
105
108
|
"""Convenience method for list(self) to get the list of parameters."""
|
|
106
109
|
return list(self)
|
|
107
110
|
|
|
108
|
-
def __iter__(self) -> Iterator[
|
|
111
|
+
def __iter__(self) -> Iterator[Any]:
|
|
109
112
|
"""Returns an iterator over the parameters of this message."""
|
|
110
113
|
return iter(self._parameters)
|