Send data between Python and the command line
A message typed at a Python prompt arrives at the command line and prints there. Then the other way round: the command line sends a message to a Python script, which answers it. The Python file doing the sending was not written for any of this. It is an ordinary script, and loading it into the Python host makes its functions addresses.
You need: the command line host, the
Python host, and three terminals: one in
the directory the command line was built in, two in osepy/host. You
have them when a prompt answers : 23 and import ose works.
1. A prompt that prints what arrives
In the first terminal, open a prompt. One line defines a function that prints what it is given; the next opens a port and calls it with each bundle that arrives:
./o.se -f o.se.osen/osen.ose
> /show : ({ (/b) /o/println }, ["/b"]) /o/defn
/show -> /_e
> (7788, /show) /o/listen
(
/socket : 3
)
2. A Python prompt with a UDP vocabulary
In the second terminal, in osepy/host, open the Python host’s prompt
with a script loaded:
python3 -m ose.repl --load examples/udp.py
examples/udp.py: 10 functions -> /o/udp/close /o/udp/main /o/udp/msg /o/udp/recv /o/udp/sender/addr /o/udp/sender/port /o/udp/sendto /o/udp/serve /o/udp/show /o/udp/sock/create
ose -- :h for help, :q to quit
ose>
udp.py is a plain script that sends OSC over UDP. It does not import
ose and declares nothing; loading it made each of its functions an
address, named after the function. Two of them:
ose> /s : () /o/udp/sock/create
()
ose> (("/hello", 42) /o/udp/msg, "127.0.0.1", 7788, /s) /o/udp/sendto
: 36
A socket, and a message of one integer sent to the port the command line opened: thirty-six bytes.
3. Where it arrived
The first terminal:
: (
/hello : 42
)
The function from step 1 printed the bundle.
4. The other way round
In the third terminal, the same script as a responder. It answers
whatever it is sent at the same address with /reply on the end:
python3 examples/udp.py --serve 7777
listening on udp/7777 -- ctrl-c to stop
At the command line, a socket of its own, a bundle sent to the responder, and the answer read back:
> /s : ("0.0.0.0", 7790) /o/udp/sock/bind
/s -> /_e
> ((/hello : 42), "127.0.0.1", 7777, /s) /o/udp/sendto
: []
> ((/s) /o/udp/recv) /o/println
: [ (
/hello/reply : 42
), "127.0.0.1" ]
: [ (
/hello/reply : 42
), "127.0.0.1" ]
The responder’s terminal says what it got, from 127.0.0.1:7790 /hello
42. /o/udp/recv answers the next datagram and who sent it; the line
prints that and then answers it, so it appears twice.
What happened
- A bundle is the unit. What crossed each way was one OSC bundle, the same bytes any OSC tool would send or read.
- The Python file became addresses. Loading an ordinary script bound each of its functions under its own name, so the prompt could call them like anything built in.
- The command line’s door is a function.
/o/listenhands each arrival to the function you name;/o/serveis the same door with “run it” as the function.
If something goes wrong
| what you see | do |
|---|---|
No module named 'ose' |
the Python host is not built, or the terminal is not in osepy/host: see its setup |
Address already in use |
another prompt holds the port: leave it with ctrl-C |
| nothing prints in step 3 | macOS asked whether o.se may accept connections and was told no: allow it and send again |
/o/udp/recv waits and nothing comes |
the responder is not running, or the port in step 4’s send differs from its |