Skip to main content

capyy — easy, encrypted networking for Python

Make Python programs talk to each other — on the same machine, on your Wi-Fi, or across the internet — control your smart lights and plugs, and run your projects with one command (cy). Zero dependencies, Python 3.9+, encrypted with TLS by default.

At its core: a server exposes actions (Python functions) and clients call them by name, with one line of code. Everything else (Wi-Fi discovery, internet relay, home automation, project files) is built on top of that.

pip install capyy

The package is published as capyy, but you import it as capy. Error messages are in French (the library was written for French speakers), and the full documentation, with examples, is at libs.zazac.link/capy.

Quick start

# server.py
import capy

api = capy.Server(4000)

@api.action("hello")
def hello(name="you"):
    return {"message": f"Hello {name}!"}

api.run()
# client.py
import capy

print(capy.call("localhost", 4000, "hello", name="Alice"))   # {'message': 'Hello Alice!'}
  • An action returns a dict, or JSON written as text with capy.json('{"text": "Hello"}').
  • Errors raised on the server come back as {"erreur": "..."} (unknown action, bad parameters, exceptions).
  • capy.call raises ConnectionError when the server does not answer.

Reading a response

reply = {"city": "Paris", "temp": "18.5", "days": [{"name": "monday"}, {"name": "tuesday"}]}

capy.get(reply, "days.1.name")          # "tuesday"  (paths go through dicts and lists)
capy.get(reply, "wind", default=0)      # 0
capy.to_float(reply, "temp")            # 18.5
capy.to_int("42"), capy.to_bool("yes")  # 42, True

to_str, to_int, to_float, to_bool, to_list and to_dict raise a ValueError that says exactly what could not be converted.

Project file: capy.config.json

Describe the whole project once, then never repeat ports or hosts:

capy new my-game     # folder + capy.config.json + server.py + client.py
cd my-game
cy run             # starts the server, runs the client, stops the server
{"name": "my-game", "version": "1.0", "mode": "local", "url": "127.0.0.1:2388", "tls": true,
 "files": {"server": "server.py", "client": "client.py"}}
app = capy.project()            # finds capy.config.json next to the script, or in a parent folder
server = app.server()           # server side
app.call("hello", nom="Izac")   # client side

mode can be local, wifi or network (with relay, key, fingerprint). Strings starting with $ are read from environment variables, e.g. "key": "$CAPY_KEY". Inside a project, the cy command runs its scripts like npm run (cy test, cy start) and its files (cy server); create a project with capy new.

From the terminal

capy call localhost:4000 hello nom=Izac        # any capy server (add --no-tls for a plain one)
capy wifi scan                                 # capy.wifi servers on your network
capy wifi call home temperature
capy network call home test --relay my-vps.example:3879 --key "$CAPY_KEY"
cy call hello nom=Izac                         # inside a project: uses capy.config.json

capy cli opens an interactive prompt (history, Tab completion, cd between projects). Output is colored in a terminal and plain text / JSON in a pipe (set NO_COLOR=1 to disable colors).

Parameters are name=value; numbers, true/false and lists are parsed (age=14 sends the number 14). The answer is printed as JSON; the exit code is 1 when the server answers {"erreur": ...}.

Encryption (TLS)

Everything is encrypted by default, with nothing to configure.

  • Each machine running a server creates its own certificate on first launch (~/.capy, using openssl) and prints its fingerprint.
  • Like SSH, a client remembers a server's fingerprint the first time (~/.capy/known_hosts.json) and raises capy.SecurityError if it ever changes.
  • The server logs every request, but never secrets: parameters whose name contains password, pwd, mdp, secret or token are shown as "***".
  • Use tls=False on both sides to talk in clear (faster on localhost).

capy.wifi — find each other on the same network

import capy.wifi

api = capy.wifi.Server("living-room")   # announces itself on the LAN, port chosen automatically
...
capy.wifi.call("living-room", "light", on=False)   # from any device on the same Wi-Fi
capy.wifi.scan()                                    # {'living-room': ('192.168.1.42', 51234)}

capy.network — across the internet, through a relay

A machine behind a home router cannot be reached from the internet, so capy.network goes through a relay running on a machine with a public IP (a VPS). Servers connect to it and register a name; clients call that name. Everything is encrypted, and the connection is kept open between calls.

capy relay 3879 my-secret-key      # on the VPS (open the port in its firewall)
import capy.network

capy.network.use("my-vps.example:3879", key="my-secret-key")
capy.network.Server("home").run()        # at home, even behind a router
capy.network.call("home", "temperature") # from anywhere

capy.domo — home automation

One way to drive lights and plugs from Philips Hue, WiZ, Shelly, Yeelight and Home Assistant (and everything Home Assistant supports), on your local network, with zero dependencies:

import capy.domo

home = capy.domo.Home()        # devices, groups and scenes live in capy.domo.json
home.scan()                    # find devices on the network
home["salon"].color("orange")  # a device, a group, or "tout" (everything)
home.scene("film")
capy.domo.serve(home)          # control it remotely through capy / capy.wifi / capy.network
capy domo scan
capy domo pair hue
capy domo salon on 30% orange

License

MIT

Metadata

Release files for capyy 0.5.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for capyy 0.5.4
File Size Uploaded
capyy-0.5.4.tar.gz 63.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for capyy 0.5.4
File Interpreter ABI Platform
capyy-0.5.4-py3-none-any.whl Python 3 none any Details

Total release size: 122.4 kB

Release files / capyy-0.5.4.tar.gz

Download URL capyy-0.5.4.tar.gz
Size 63.0 kB
Tags Source
SHA-256 checksum
How to use checksums
492b95027f73e198c0d4dfd98188bd599787d546810dabd685902e78118f913b
BLAKE2b-256 checksum
How to use checksums
64bae3f4aeb75ff99e24edd8294faa4be1319286e9088e56931b5c867df7aead
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / capyy-0.5.4-py3-none-any.whl

Download URL capyy-0.5.4-py3-none-any.whl
Size 59.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8113273145c5f3c7ff85dd02f78187bc4847bf245f1e73a858a23463b83b67fd
BLAKE2b-256 checksum
How to use checksums
85b65d1b591c2553e3e260506f01c88f675c76cbcc88c881621e6c524657f25a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.5.4 This release

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page