capyy 0.5.0__tar.gz → 0.5.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.
Files changed (27) hide show
  1. {capyy-0.5.0 → capyy-0.5.2}/PKG-INFO +15 -11
  2. {capyy-0.5.0 → capyy-0.5.2}/README.md +13 -9
  3. {capyy-0.5.0 → capyy-0.5.2}/capy/__init__.py +1 -1
  4. {capyy-0.5.0 → capyy-0.5.2}/capy/__main__.py +34 -16
  5. {capyy-0.5.0 → capyy-0.5.2}/capy/_project.py +4 -4
  6. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/__init__.py +2 -2
  7. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/__main__.py +23 -23
  8. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/_homeassistant.py +1 -1
  9. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/_hue.py +2 -2
  10. {capyy-0.5.0 → capyy-0.5.2}/capy/network.py +10 -6
  11. {capyy-0.5.0 → capyy-0.5.2}/capyy.egg-info/PKG-INFO +15 -11
  12. {capyy-0.5.0 → capyy-0.5.2}/capyy.egg-info/entry_points.txt +1 -0
  13. {capyy-0.5.0 → capyy-0.5.2}/pyproject.toml +4 -3
  14. {capyy-0.5.0 → capyy-0.5.2}/LICENSE +0 -0
  15. {capyy-0.5.0 → capyy-0.5.2}/capy/_tls.py +0 -0
  16. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/_base.py +0 -0
  17. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/_net.py +0 -0
  18. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/_shelly.py +0 -0
  19. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/_wiz.py +0 -0
  20. {capyy-0.5.0 → capyy-0.5.2}/capy/domo/_yeelight.py +0 -0
  21. {capyy-0.5.0 → capyy-0.5.2}/capy/wifi.py +0 -0
  22. {capyy-0.5.0 → capyy-0.5.2}/capyy.egg-info/SOURCES.txt +0 -0
  23. {capyy-0.5.0 → capyy-0.5.2}/capyy.egg-info/dependency_links.txt +0 -0
  24. {capyy-0.5.0 → capyy-0.5.2}/capyy.egg-info/top_level.txt +0 -0
  25. {capyy-0.5.0 → capyy-0.5.2}/setup.cfg +0 -0
  26. {capyy-0.5.0 → capyy-0.5.2}/tests/test_capy.py +0 -0
  27. {capyy-0.5.0 → capyy-0.5.2}/tests/test_domo.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: capyy
3
- Version: 0.5.0
4
- Summary: Tiny encrypted JSON-over-TCP APIs: call a function in another program, on your Wi-Fi or across the internet
3
+ Version: 0.5.2
4
+ Summary: Easy, encrypted networking for Python: programs that talk (local, Wi-Fi, internet), home automation, and projects run with cy
5
5
  Author: Izac
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://libs.zazac.link/capy/
@@ -20,10 +20,14 @@ Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
21
  Dynamic: license-file
22
22
 
23
- # capyy — tiny encrypted JSON-over-TCP APIs
23
+ # capyy — easy, encrypted networking for Python
24
24
 
25
- Call a function in another Python program — on the same machine, on your Wi-Fi, or across the internet —
26
- with one line of code. Zero dependencies, Python 3.9+, encrypted with TLS by default.
25
+ Make Python programs talk to each other — on the same machine, on your Wi-Fi, or across the internet —
26
+ control your smart lights and plugs, and run your projects with one command (`cy`).
27
+ Zero dependencies, Python 3.9+, encrypted with TLS by default.
28
+
29
+ At its core: a **server** exposes *actions* (Python functions) and **clients** call them by name, with one line of code.
30
+ Everything else (Wi-Fi discovery, internet relay, home automation, project files) is built on top of that.
27
31
 
28
32
  ```bash
29
33
  pip install capyy
@@ -78,7 +82,7 @@ what could not be converted.
78
82
  Describe the whole project once, then never repeat ports or hosts:
79
83
 
80
84
  ```bash
81
- python3 -m capy new my-game # folder + capy.config.json + server.py + client.py
85
+ capy new my-game # folder + capy.config.json + server.py + client.py
82
86
  cd my-game
83
87
  cy run # starts the server, runs the client, stops the server
84
88
  ```
@@ -95,7 +99,7 @@ app.call("hello", nom="Izac") # client side
95
99
  ```
96
100
 
97
101
  `mode` can be `local`, `wifi` or `network` (with `relay`, `key`, `fingerprint`). Strings starting with `$` are read
98
- 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 `python3 -m capy new`.
102
+ 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`.
99
103
 
100
104
  ## Encryption (TLS)
101
105
 
@@ -127,7 +131,7 @@ A machine behind a home router cannot be reached from the internet, so `capy.net
127
131
  clients call that name. Everything is encrypted, and the connection is kept open between calls.
128
132
 
129
133
  ```bash
130
- python3 -m capy.network 3879 my-secret-key # on the VPS (open the port in its firewall)
134
+ capy relay 3879 my-secret-key # on the VPS (open the port in its firewall)
131
135
  ```
132
136
 
133
137
  ```python
@@ -154,9 +158,9 @@ capy.domo.serve(home) # control it remotely through capy / capy.wifi /
154
158
  ```
155
159
 
156
160
  ```bash
157
- python3 -m capy.domo scan
158
- python3 -m capy.domo pair hue
159
- python3 -m capy.domo salon on 30% orange
161
+ capy domo scan
162
+ capy domo pair hue
163
+ capy domo salon on 30% orange
160
164
  ```
161
165
 
162
166
  ## License
@@ -1,7 +1,11 @@
1
- # capyy — tiny encrypted JSON-over-TCP APIs
1
+ # capyy — easy, encrypted networking for Python
2
2
 
3
- Call a function in another Python program — on the same machine, on your Wi-Fi, or across the internet —
4
- with one line of code. Zero dependencies, Python 3.9+, encrypted with TLS by default.
3
+ Make Python programs talk to each other — on the same machine, on your Wi-Fi, or across the internet —
4
+ control your smart lights and plugs, and run your projects with one command (`cy`).
5
+ Zero dependencies, Python 3.9+, encrypted with TLS by default.
6
+
7
+ At its core: a **server** exposes *actions* (Python functions) and **clients** call them by name, with one line of code.
8
+ Everything else (Wi-Fi discovery, internet relay, home automation, project files) is built on top of that.
5
9
 
6
10
  ```bash
7
11
  pip install capyy
@@ -56,7 +60,7 @@ what could not be converted.
56
60
  Describe the whole project once, then never repeat ports or hosts:
57
61
 
58
62
  ```bash
59
- python3 -m capy new my-game # folder + capy.config.json + server.py + client.py
63
+ capy new my-game # folder + capy.config.json + server.py + client.py
60
64
  cd my-game
61
65
  cy run # starts the server, runs the client, stops the server
62
66
  ```
@@ -73,7 +77,7 @@ app.call("hello", nom="Izac") # client side
73
77
  ```
74
78
 
75
79
  `mode` can be `local`, `wifi` or `network` (with `relay`, `key`, `fingerprint`). Strings starting with `$` are read
76
- 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 `python3 -m capy new`.
80
+ 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`.
77
81
 
78
82
  ## Encryption (TLS)
79
83
 
@@ -105,7 +109,7 @@ A machine behind a home router cannot be reached from the internet, so `capy.net
105
109
  clients call that name. Everything is encrypted, and the connection is kept open between calls.
106
110
 
107
111
  ```bash
108
- python3 -m capy.network 3879 my-secret-key # on the VPS (open the port in its firewall)
112
+ capy relay 3879 my-secret-key # on the VPS (open the port in its firewall)
109
113
  ```
110
114
 
111
115
  ```python
@@ -132,9 +136,9 @@ capy.domo.serve(home) # control it remotely through capy / capy.wifi /
132
136
  ```
133
137
 
134
138
  ```bash
135
- python3 -m capy.domo scan
136
- python3 -m capy.domo pair hue
137
- python3 -m capy.domo salon on 30% orange
139
+ capy domo scan
140
+ capy domo pair hue
141
+ capy domo salon on 30% orange
138
142
  ```
139
143
 
140
144
  ## License
@@ -1,4 +1,4 @@
1
- # capy : mini-API en TCP, une ligne JSON par requête / réponse, chiffrée (TLS)
1
+ # capy : le réseau facile en Python (le cœur : un serveur d'actions et un client, une ligne JSON par requête, chiffré TLS)
2
2
 
3
3
  import json as jsonlib # "json" est pris par capy.json()
4
4
  import socket
@@ -1,16 +1,19 @@
1
- # Les commandes d'un projet capy (tout vient de capy.config.json)
1
+ # Deux commandes, installées avec capy :
2
2
  #
3
- # cy : seulement DANS un projet capy (un dossier avec capy.config.json, ou en dessous)
3
+ # cy : DANS un projet capy (un dossier avec capy.config.json, ou en dessous)
4
4
  # cy -> montre le projet (nom, mode, adresse, fichiers, scripts…)
5
5
  # cy NOM [args…] -> lance le script NOM de "scripts" (comme npm run)
6
6
  # cy scripts -> liste les scripts
7
7
  # cy server / cy client -> lance un fichier de "files"
8
8
  # cy run -> lance le serveur en fond, puis le client, puis arrête le serveur
9
9
  #
10
- # python3 -m capy : tout ce que fait cy, plus créer un projet
11
- # python3 -m capy new NOM [mode] -> crée un dossier NOM avec capy.config.json, server.py, client.py
12
- # python3 -m capy init [nom] [mode] -> crée juste capy.config.json ici
10
+ # capy : tout le reste (et tout ce que fait cy)
11
+ # capy new NOM [mode] -> crée un dossier NOM avec capy.config.json, server.py, client.py
12
+ # capy init [nom] [mode] -> crée juste capy.config.json ici
13
+ # capy domo … -> la domotique (capy domo help)
14
+ # capy relay PORT [CLÉ] -> lance un relais capy.network (sur le VPS)
13
15
  # mode : local (par défaut), wifi ou network
16
+ # python3 -m capy = capy (si la commande n'est pas dans le PATH)
14
17
 
15
18
  import difflib
16
19
  import socket
@@ -27,9 +30,11 @@ USAGE = f"""Dans un projet capy ({FILE_NAME}) :
27
30
  cy scripts liste les scripts
28
31
  cy server / client lance un fichier de "files"
29
32
  cy run serveur en fond + client, puis arrête le serveur
30
- Créer un projet :
31
- python3 -m capy new NOM [mode] un dossier complet (config, server.py, client.py)
32
- python3 -m capy init [nom] [mode] juste {FILE_NAME} ici
33
+ Partout :
34
+ capy new NOM [mode] crée un projet complet (config, server.py, client.py)
35
+ capy init [nom] [mode] crée juste {FILE_NAME} ici
36
+ capy domo … la domotique (capy domo help)
37
+ capy relay PORT [CLÉ] lance un relais capy.network
33
38
  modes : {", ".join(MODES)}"""
34
39
 
35
40
 
@@ -37,9 +42,9 @@ Créer un projet :
37
42
  def _project():
38
43
  path = find(".")
39
44
  if path is None:
40
- sys.exit(f"cy marche dans un projet capy, et il n'y a pas de {FILE_NAME} ici ni au-dessus.\n"
41
- f" Crée un projet : python3 -m capy new mon-projet\n"
42
- f" ou juste le fichier : python3 -m capy init")
45
+ sys.exit(f"Pas de {FILE_NAME} ici ni au-dessus : ce dossier n'est pas un projet capy.\n"
46
+ f" Crée un projet : capy new mon-projet\n"
47
+ f" ou juste le fichier : capy init")
43
48
  try:
44
49
  return project(path)
45
50
  except ValueError as e:
@@ -111,12 +116,20 @@ def main(args):
111
116
  if command in ("-h", "--help", "help"):
112
117
  print(USAGE)
113
118
  return
119
+ if command == "domo": # capy domo salon on
120
+ from .domo.__main__ import cli as domo_cli
121
+ domo_cli(args[1:])
122
+ return
123
+ if command in ("relay", "network"): # capy relay 3879 CLÉ
124
+ from .network import cli as relay_cli
125
+ relay_cli(args[1:])
126
+ return
114
127
  if command in ("init", "new"):
115
128
  rest = args[1:]
116
129
  mode = next((a for a in rest if a in MODES), "local")
117
130
  name = next((a for a in rest if a not in MODES), None)
118
131
  if command == "new" and not name:
119
- sys.exit("Usage : python3 -m capy new NOM [mode]")
132
+ sys.exit("Usage : capy new NOM [mode]")
120
133
  try:
121
134
  path = new(name, mode) / FILE_NAME if command == "new" else init(name=name, mode=mode)
122
135
  except (FileExistsError, ValueError) as e:
@@ -157,13 +170,18 @@ def main(args):
157
170
  sys.exit(f"capy : commande, script ou fichier {command!r} inconnu (possibles : {', '.join(names)})\n\n{USAGE}")
158
171
 
159
172
 
160
- # La commande cy : seulement les commandes d'un projet (pas new ni init, qui créent un projet)
173
+ # La commande cy : seulement les commandes d'un projet
161
174
  def cli():
162
175
  args = sys.argv[1:]
163
- if args[:1] in (["new"], ["init"]):
164
- sys.exit(f"cy sert dans un projet existant ; pour en créer un : python3 -m capy {' '.join(args)}")
176
+ if args[:1] in (["new"], ["init"], ["domo"], ["relay"], ["network"]):
177
+ sys.exit(f"cy sert dans un projet capy ; pour ça, c'est la commande capy : capy {' '.join(args)}")
165
178
  main(args)
166
179
 
167
180
 
168
- if __name__ == "__main__": # python3 -m capy : tout, y compris new et init
181
+ # La commande capy (et python3 -m capy) : tout
182
+ def capy_cli():
169
183
  main(sys.argv[1:])
184
+
185
+
186
+ if __name__ == "__main__":
187
+ capy_cli()
@@ -46,7 +46,7 @@ FIELDS = {
46
46
 
47
47
  EXAMPLE = {"name": "mon-projet", "mode": "local", "host": "localhost", "port": 4000, "tls": True,
48
48
  "files": {"server": "server.py", "client": "client.py"}}
49
- COMMANDS = ("init", "new", "run", "scripts", "help") # Mots réservés de cy / python3 -m capy (pas des noms de fichiers ni de scripts)
49
+ COMMANDS = ("init", "new", "run", "scripts", "help", "domo", "relay") # Mots réservés de cy / capy (pas des noms de fichiers ni de scripts)
50
50
 
51
51
 
52
52
  # Dossier du script lancé (comme simplesuit.json) ; sans script (python3 -c, REPL) -> dossier actuel
@@ -274,7 +274,7 @@ def project(path=None) -> Project:
274
274
  if found is None:
275
275
  raise FileNotFoundError(
276
276
  f"capy.project : aucun {FILE_NAME} trouvé dans {_main_dir()} ni au-dessus.\n"
277
- f" Crée-le avec : python3 -m capy init\n"
277
+ f" Crée-le avec : capy init\n"
278
278
  f" ou écris-le toi-même, par exemple : {jsonlib.dumps(EXAMPLE, ensure_ascii=False)}"
279
279
  )
280
280
  return Project(found)
@@ -284,7 +284,7 @@ def project(path=None) -> Project:
284
284
  return Project(path / FILE_NAME if path.is_dir() else path)
285
285
 
286
286
 
287
- # Écrire un capy.config.json de départ (python3 -m capy init [nom] [mode])
287
+ # Écrire un capy.config.json de départ (capy init [nom] [mode])
288
288
  def init(folder=None, name=None, mode="local"):
289
289
  if mode not in MODES:
290
290
  raise ValueError(f"capy init : mode {mode!r} inconnu, choisis parmi : {', '.join(MODES)}")
@@ -331,7 +331,7 @@ print(capy.get(reponse, "message"))
331
331
  '''
332
332
 
333
333
 
334
- # Créer un projet complet : dossier + capy.config.json + server.py + client.py (python3 -m capy new nom)
334
+ # Créer un projet complet : dossier + capy.config.json + server.py + client.py (capy new nom)
335
335
  def new(name, mode="local", parent=None):
336
336
  folder = pth.Path(parent or pth.Path.cwd()) / name
337
337
  if folder.exists() and any(folder.iterdir()):
@@ -253,14 +253,14 @@ class Home:
253
253
  if host in self.hue:
254
254
  lights += _hue.lights(host, _env(self.hue[host]))
255
255
  else:
256
- self.hints.append(f"Pont Hue trouvé à {host} : appaire-le avec python3 -m capy.domo pair hue {host}")
256
+ self.hints.append(f"Pont Hue trouvé à {host} : appaire-le avec capy domo pair hue {host}")
257
257
  return lights
258
258
 
259
259
  def _scan_homeassistant(self, timeout, addresses):
260
260
  if self.homeassistant:
261
261
  return _homeassistant.entities(_env(self.homeassistant["url"]), _env(self.homeassistant["token"]))
262
262
  for url in _homeassistant.servers(timeout, addresses.get("homeassistant")):
263
- self.hints.append(f"Home Assistant trouvé à {url} : python3 -m capy.domo pair homeassistant {url}")
263
+ self.hints.append(f"Home Assistant trouvé à {url} : capy domo pair homeassistant {url}")
264
264
  return []
265
265
 
266
266
  # --- Appairage --------------------------------------------
@@ -1,13 +1,13 @@
1
- # python3 -m capy.domo : piloter la maison depuis le terminal
1
+ # capy domo : piloter la maison depuis le terminal
2
2
  #
3
- # python3 -m capy.domo scan chercher les appareils du réseau (et les ajouter)
4
- # python3 -m capy.domo pair hue [IP] appairer un pont Hue (appuyer sur son bouton)
5
- # python3 -m capy.domo pair homeassistant URL brancher Home Assistant (jeton demandé)
6
- # python3 -m capy.domo list les appareils, groupes et scènes, avec leur état
7
- # python3 -m capy.domo salon on 30% orange allumer, luminosité, couleur (ou off, toggle, 2700K, chaud…)
8
- # python3 -m capy.domo scene film lancer une scène
9
- # python3 -m capy.domo serve rendre la maison pilotable à distance
10
- # python3 -m capy.domo --remote salon off piloter une maison à distance (capy.config.json)
3
+ # capy domo scan chercher les appareils du réseau (et les ajouter)
4
+ # capy domo pair hue [IP] appairer un pont Hue (appuyer sur son bouton)
5
+ # capy domo pair homeassistant URL brancher Home Assistant (jeton demandé)
6
+ # capy domo list les appareils, groupes et scènes, avec leur état
7
+ # capy domo salon on 30% orange allumer, luminosité, couleur (ou off, toggle, 2700K, chaud…)
8
+ # capy domo scene film lancer une scène
9
+ # capy domo serve rendre la maison pilotable à distance
10
+ # capy domo --remote salon off piloter une maison à distance (capy.config.json)
11
11
 
12
12
  import getpass
13
13
  import os
@@ -20,14 +20,14 @@ import capy
20
20
  from . import FILE_NAME, WHITES, Home, Remote, _hue, find, serve, to_kelvin, to_rgb
21
21
 
22
22
  USAGE = """Usage :
23
- python3 -m capy.domo scan chercher les appareils du réseau
24
- python3 -m capy.domo pair hue [IP] appairer un pont Hue
25
- python3 -m capy.domo pair homeassistant URL brancher Home Assistant
26
- python3 -m capy.domo list appareils, groupes, scènes et état
27
- python3 -m capy.domo NOM on|off|toggle|50%|orange|#FF7800|2700K|chaud …
28
- python3 -m capy.domo scene NOM lancer une scène
29
- python3 -m capy.domo serve pilotable à distance
30
- python3 -m capy.domo --remote NOM … piloter une maison à distance"""
23
+ capy domo scan chercher les appareils du réseau
24
+ capy domo pair hue [IP] appairer un pont Hue
25
+ capy domo pair homeassistant URL brancher Home Assistant
26
+ capy domo list appareils, groupes, scènes et état
27
+ capy domo NOM on|off|toggle|50%|orange|#FF7800|2700K|chaud …
28
+ capy domo scene NOM lancer une scène
29
+ capy domo serve pilotable à distance
30
+ capy domo --remote NOM … piloter une maison à distance"""
31
31
 
32
32
 
33
33
  # "on 30% orange" -> {"on": True, "brightness": 30, "color": "orange"} (ou "toggle")
@@ -97,7 +97,7 @@ def main(args):
97
97
  if brand == "hue":
98
98
  hosts = rest[1:] or _hue.bridges()
99
99
  if not hosts:
100
- sys.exit("Aucun pont Hue trouvé : donne son IP, ex : python3 -m capy.domo pair hue 192.168.1.10")
100
+ sys.exit("Aucun pont Hue trouvé : donne son IP, ex : capy domo pair hue 192.168.1.10")
101
101
  host = hosts[0]
102
102
  input(f"Appuie sur le gros bouton rond du pont Hue ({host}), puis sur Entrée… ")
103
103
  for _ in range(30):
@@ -110,7 +110,7 @@ def main(args):
110
110
  sys.exit("Le pont n'a pas vu le bouton : réessaie (tu as 30 s après l'appui)")
111
111
  elif brand == "homeassistant":
112
112
  if len(rest) < 2:
113
- sys.exit("Donne l'adresse : python3 -m capy.domo pair homeassistant http://homeassistant.local:8123")
113
+ sys.exit("Donne l'adresse : capy domo pair homeassistant http://homeassistant.local:8123")
114
114
  if os.environ.get("HA_TOKEN"):
115
115
  token = "$HA_TOKEN"
116
116
  print("Jeton lu dans la variable HA_TOKEN")
@@ -118,7 +118,7 @@ def main(args):
118
118
  token = getpass.getpass("Jeton longue durée (Profil -> Sécurité dans Home Assistant) : ")
119
119
  added = home.pair_homeassistant(rest[1], token)
120
120
  else:
121
- sys.exit("Usage : python3 -m capy.domo pair hue [IP] ou pair homeassistant URL")
121
+ sys.exit("Usage : capy domo pair hue [IP] ou pair homeassistant URL")
122
122
  for device in added:
123
123
  print(f" + {device.name:<18} {device.brand}")
124
124
  print(f"{len(added)} appareil(s) ajouté(s) dans {home.save()}")
@@ -131,7 +131,7 @@ def main(args):
131
131
  else:
132
132
  names, groups, scenes = list(home.devices), home.groups, list(home.scenes)
133
133
  states = home.all().state() if home.devices else {}
134
- print("Appareils :" if names else "Aucun appareil : lance python3 -m capy.domo scan")
134
+ print("Appareils :" if names else "Aucun appareil : lance capy domo scan")
135
135
  for name in names:
136
136
  print(show_state(name, states.get(name, {"reachable": False})))
137
137
  if groups:
@@ -143,7 +143,7 @@ def main(args):
143
143
 
144
144
  elif command == "scene":
145
145
  if not rest:
146
- sys.exit("Usage : python3 -m capy.domo scene NOM")
146
+ sys.exit("Usage : capy domo scene NOM")
147
147
  home.scene(rest[0])
148
148
  print(f"Scène {rest[0]!r} lancée")
149
149
 
@@ -170,7 +170,7 @@ def main(args):
170
170
  print(f"{command} : ok")
171
171
 
172
172
 
173
- # Point d'entrée de python3 -m capy.domo
173
+ # Point d'entrée de capy domo
174
174
  def cli(args=None):
175
175
  try:
176
176
  main(sys.argv[1:] if args is None else args)
@@ -32,7 +32,7 @@ class HassEntity(Device):
32
32
 
33
33
  def _request(self, method, path, body=None):
34
34
  if not self.url or not self.token:
35
- raise ConnectionError("Home Assistant pas configuré : python3 -m capy.domo pair homeassistant URL")
35
+ raise ConnectionError("Home Assistant pas configuré : capy domo pair homeassistant URL")
36
36
  return request(self.url, self.token, method, path, body)
37
37
 
38
38
  def _apply(self, changes):
@@ -31,7 +31,7 @@ def _check(answer):
31
31
  return answer
32
32
  error = errors[0]
33
33
  if error.get("type") == 1:
34
- raise ConnectionError("le pont Hue ne te connaît pas : refais python3 -m capy.domo pair hue")
34
+ raise ConnectionError("le pont Hue ne te connaît pas : refais capy domo pair hue")
35
35
  raise ConnectionError(f"pont Hue : {error.get('description', error)}")
36
36
 
37
37
 
@@ -78,7 +78,7 @@ class HueLight(Device):
78
78
 
79
79
  def _path(self, end=""):
80
80
  if not self.user:
81
- raise ConnectionError(f"pas d'appairage avec le pont {self.host} : python3 -m capy.domo pair hue {self.host}")
81
+ raise ConnectionError(f"pas d'appairage avec le pont {self.host} : capy domo pair hue {self.host}")
82
82
  return f"/api/{self.user}/lights/{self.id}{end}"
83
83
 
84
84
  def _apply(self, changes):
@@ -3,7 +3,7 @@
3
3
  # Les serveurs s'y connectent (même derrière une box) et s'enregistrent sous un nom,
4
4
  # les clients appellent un nom : le relais fait passer la demande et la réponse.
5
5
  #
6
- # Sur le VPS : python3 -m capy.network 3879 motdepasse
6
+ # Sur le VPS : capy relay 3879 motdepasse
7
7
  # Partout ailleurs :
8
8
  # capy.network.use("mon-vps.fr:3879", key="motdepasse")
9
9
  # capy.network.Server("maison").run() / capy.network.call("maison", "test")
@@ -495,9 +495,13 @@ def call(name, action, /, **params) -> Any:
495
495
  return reply["response"]
496
496
 
497
497
 
498
- # Lancer un relais depuis le terminal : python3 -m capy.network 3879 motdepasse
498
+ # Lancer un relais depuis le terminal : capy relay 3879 motdepasse (ou capy relay 3879 motdepasse)
499
+ def cli(args=None):
500
+ args = sys.argv[1:] if args is None else args
501
+ if not args or not args[0].isdigit():
502
+ sys.exit("Usage : capy relay PORT [CLÉ] (ex : capy relay 3879 \"$CAPY_KEY\")")
503
+ Relay(int(args[0]), key=args[1] if len(args) > 1 else None).run()
504
+
505
+
499
506
  if __name__ == "__main__":
500
- if len(sys.argv) < 2 or not sys.argv[1].isdigit():
501
- print("Usage : python3 -m capy.network PORT [CLÉ]")
502
- sys.exit(1)
503
- Relay(int(sys.argv[1]), key=sys.argv[2] if len(sys.argv) > 2 else None).run()
507
+ cli()
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: capyy
3
- Version: 0.5.0
4
- Summary: Tiny encrypted JSON-over-TCP APIs: call a function in another program, on your Wi-Fi or across the internet
3
+ Version: 0.5.2
4
+ Summary: Easy, encrypted networking for Python: programs that talk (local, Wi-Fi, internet), home automation, and projects run with cy
5
5
  Author: Izac
6
6
  License-Expression: MIT
7
7
  Project-URL: Homepage, https://libs.zazac.link/capy/
@@ -20,10 +20,14 @@ Description-Content-Type: text/markdown
20
20
  License-File: LICENSE
21
21
  Dynamic: license-file
22
22
 
23
- # capyy — tiny encrypted JSON-over-TCP APIs
23
+ # capyy — easy, encrypted networking for Python
24
24
 
25
- Call a function in another Python program — on the same machine, on your Wi-Fi, or across the internet —
26
- with one line of code. Zero dependencies, Python 3.9+, encrypted with TLS by default.
25
+ Make Python programs talk to each other — on the same machine, on your Wi-Fi, or across the internet —
26
+ control your smart lights and plugs, and run your projects with one command (`cy`).
27
+ Zero dependencies, Python 3.9+, encrypted with TLS by default.
28
+
29
+ At its core: a **server** exposes *actions* (Python functions) and **clients** call them by name, with one line of code.
30
+ Everything else (Wi-Fi discovery, internet relay, home automation, project files) is built on top of that.
27
31
 
28
32
  ```bash
29
33
  pip install capyy
@@ -78,7 +82,7 @@ what could not be converted.
78
82
  Describe the whole project once, then never repeat ports or hosts:
79
83
 
80
84
  ```bash
81
- python3 -m capy new my-game # folder + capy.config.json + server.py + client.py
85
+ capy new my-game # folder + capy.config.json + server.py + client.py
82
86
  cd my-game
83
87
  cy run # starts the server, runs the client, stops the server
84
88
  ```
@@ -95,7 +99,7 @@ app.call("hello", nom="Izac") # client side
95
99
  ```
96
100
 
97
101
  `mode` can be `local`, `wifi` or `network` (with `relay`, `key`, `fingerprint`). Strings starting with `$` are read
98
- 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 `python3 -m capy new`.
102
+ 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`.
99
103
 
100
104
  ## Encryption (TLS)
101
105
 
@@ -127,7 +131,7 @@ A machine behind a home router cannot be reached from the internet, so `capy.net
127
131
  clients call that name. Everything is encrypted, and the connection is kept open between calls.
128
132
 
129
133
  ```bash
130
- python3 -m capy.network 3879 my-secret-key # on the VPS (open the port in its firewall)
134
+ capy relay 3879 my-secret-key # on the VPS (open the port in its firewall)
131
135
  ```
132
136
 
133
137
  ```python
@@ -154,9 +158,9 @@ capy.domo.serve(home) # control it remotely through capy / capy.wifi /
154
158
  ```
155
159
 
156
160
  ```bash
157
- python3 -m capy.domo scan
158
- python3 -m capy.domo pair hue
159
- python3 -m capy.domo salon on 30% orange
161
+ capy domo scan
162
+ capy domo pair hue
163
+ capy domo salon on 30% orange
160
164
  ```
161
165
 
162
166
  ## License
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
+ capy = capy.__main__:capy_cli
2
3
  cy = capy.__main__:cli
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "capyy"
7
- version = "0.5.0"
8
- description = "Tiny encrypted JSON-over-TCP APIs: call a function in another program, on your Wi-Fi or across the internet"
7
+ version = "0.5.2"
8
+ description = "Easy, encrypted networking for Python: programs that talk (local, Wi-Fi, internet), home automation, and projects run with cy"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
11
  license = "MIT"
@@ -25,7 +25,8 @@ classifiers = [
25
25
  ]
26
26
 
27
27
  [project.scripts]
28
- cy = "capy.__main__:cli" # La commande cy (= python3 -m capy)
28
+ cy = "capy.__main__:cli" # Dans un projet : cy start, cy test…
29
+ capy = "capy.__main__:capy_cli" # Partout : capy new, capy domo, capy relay… (= python3 -m capy)
29
30
 
30
31
  [project.urls]
31
32
  Homepage = "https://libs.zazac.link/capy/"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes