canvas 0.16.0__py3-none-any.whl → 0.17.0__py3-none-any.whl

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.

Potentially problematic release.


This version of canvas might be problematic. Click here for more details.

@@ -0,0 +1,9 @@
1
+ syntax = "proto3";
2
+
3
+ message ReloadPluginsRequest {
4
+
5
+ }
6
+
7
+ message ReloadPluginsResponse {
8
+ bool success = 1;
9
+ }
@@ -0,0 +1,12 @@
1
+ syntax = 'proto3';
2
+
3
+ import "canvas_generated/messages/events.proto";
4
+ import "canvas_generated/messages/plugins.proto";
5
+
6
+ package canvas;
7
+
8
+ service PluginRunner {
9
+ rpc HandleEvent (Event) returns (stream EventResponse);
10
+
11
+ rpc ReloadPlugins (ReloadPluginsRequest) returns (stream ReloadPluginsResponse);
12
+ }
settings.py CHANGED
@@ -12,12 +12,14 @@ ENV = os.getenv("ENV", "development")
12
12
  IS_PRODUCTION = ENV == "production"
13
13
  IS_TESTING = env_to_bool("IS_TESTING", "pytest" in sys.argv[0] or sys.argv[0] == "-c")
14
14
  CUSTOMER_IDENTIFIER = os.getenv("CUSTOMER_IDENTIFIER", "local")
15
+ APP_NAME = os.getenv("APP_NAME")
15
16
 
16
17
  INTEGRATION_TEST_URL = os.getenv("INTEGRATION_TEST_URL")
17
18
  INTEGRATION_TEST_CLIENT_ID = os.getenv("INTEGRATION_TEST_CLIENT_ID")
18
19
  INTEGRATION_TEST_CLIENT_SECRET = os.getenv("INTEGRATION_TEST_CLIENT_SECRET")
19
20
 
20
21
  GRAPHQL_ENDPOINT = os.getenv("GRAPHQL_ENDPOINT", "http://localhost:8000/plugins-graphql")
22
+ REDIS_ENDPOINT = os.getenv("REDIS_ENDPOINT", f"redis://{APP_NAME}-redis:6379")
21
23
 
22
24
  INSTALLED_APPS = [
23
25
  "canvas_sdk.v1",
@@ -68,7 +70,8 @@ PLUGIN_DIRECTORY = os.getenv(
68
70
  else "./custom-plugins"
69
71
  ),
70
72
  )
71
-
73
+ PLUGINS_PUBSUB_CHANNEL = os.getenv("PLUGINS_PUBSUB_CHANNEL", default="plugins")
74
+ CHANNEL_NAME = f"{CUSTOMER_IDENTIFIER}:{PLUGINS_PUBSUB_CHANNEL}"
72
75
  MANIFEST_FILE_NAME = "CANVAS_MANIFEST.json"
73
76
 
74
77
  SECRETS_FILE_NAME = "SECRETS.json"
@@ -1,3 +0,0 @@
1
- [console_scripts]
2
- canvas=canvas_cli.main:app
3
-
@@ -1,92 +0,0 @@
1
- #!/usr/bin/env python
2
-
3
- import os
4
- import pickle
5
- from pathlib import Path
6
- from subprocess import STDOUT, CalledProcessError, check_output
7
-
8
- import redis
9
-
10
- from plugin_runner.plugin_installer import install_plugins
11
-
12
- APP_NAME = os.getenv("APP_NAME")
13
-
14
- CUSTOMER_IDENTIFIER = os.getenv("CUSTOMER_IDENTIFIER")
15
- PLUGINS_PUBSUB_CHANNEL = os.getenv("PLUGINS_PUBSUB_CHANNEL", default="plugins")
16
-
17
- CHANNEL_NAME = f"{CUSTOMER_IDENTIFIER}:{PLUGINS_PUBSUB_CHANNEL}"
18
-
19
- REDIS_ENDPOINT = os.getenv("REDIS_ENDPOINT", f"redis://{APP_NAME}-redis:6379")
20
-
21
- try:
22
- CLIENT_ID = Path("/app/container-unique-id.txt").read_text()
23
- except FileNotFoundError:
24
- CLIENT_ID = "non-unique"
25
-
26
-
27
- def get_client() -> tuple[redis.Redis, redis.client.PubSub]:
28
- """Return a Redis client and pubsub object."""
29
- client = redis.Redis.from_url(REDIS_ENDPOINT)
30
- pubsub = client.pubsub()
31
-
32
- return client, pubsub
33
-
34
-
35
- def publish_message(message: dict) -> None:
36
- """Publish a message to the pubsub channel."""
37
- client, _ = get_client()
38
-
39
- message_with_id = {**message, "client_id": CLIENT_ID}
40
-
41
- client.publish(CHANNEL_NAME, pickle.dumps(message_with_id))
42
- client.close()
43
-
44
-
45
- def main() -> None:
46
- """Listen for messages on the pubsub channel and restart the plugin-runner."""
47
- print("plugin-synchronizer: starting")
48
- try:
49
- print("plugin-synchronizer: installing plugins after web container start")
50
- install_plugins()
51
- print("plugin-synchronizer: sending SIGHUP to plugin-runner")
52
- check_output(["circusctl", "signal", "plugin-runner", "1"], cwd="/app", stderr=STDOUT)
53
- except CalledProcessError as e:
54
- print("plugin-synchronizer: `install_plugins` failed:", e)
55
-
56
- _, pubsub = get_client()
57
-
58
- pubsub.psubscribe(CHANNEL_NAME)
59
-
60
- for message in pubsub.listen():
61
- if not message:
62
- continue
63
-
64
- message_type = message.get("type", "")
65
-
66
- if message_type != "pmessage":
67
- continue
68
-
69
- data = pickle.loads(message.get("data", pickle.dumps({})))
70
-
71
- if "action" not in data or "client_id" not in data:
72
- continue
73
-
74
- if data["action"] == "restart":
75
- # Run the plugin installer process
76
- try:
77
- print("plugin-synchronizer: installing plugins after receiving restart message")
78
- install_plugins()
79
- except CalledProcessError as e:
80
- print("plugin-synchronizer: `install_plugins` failed:", e)
81
-
82
- try:
83
- print("plugin-synchronizer: sending SIGHUP to plugin-runner")
84
- check_output(
85
- ["circusctl", "signal", "plugin-runner", "1"], cwd="/app", stderr=STDOUT
86
- )
87
- except CalledProcessError as e:
88
- print("plugin-synchronizer: `circusctl signal plugin-runner 1` failed:", e)
89
-
90
-
91
- if __name__ == "__main__":
92
- main()