poetry-plugin-ivcap 0.2.6__tar.gz → 0.2.8__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: poetry-plugin-ivcap
3
- Version: 0.2.6
3
+ Version: 0.2.8
4
4
  Summary: A custom Poetry command for IVCAP deployments
5
5
  License: MIT
6
6
  Author: Max Ott
@@ -0,0 +1,47 @@
1
+ #
2
+ # Copyright (c) 2025 Commonwealth Scientific and Industrial Research Organisation (CSIRO). All rights reserved.
3
+ # Use of this source code is governed by a BSD-style license that can be
4
+ # found in the LICENSE file. See the AUTHORS file for names of contributors.
5
+ #
6
+
7
+ PLUGIN_NAME = "poetry-plugin-ivcap"
8
+ PLUGIN_CMD = "ivcap"
9
+
10
+ SERVICE_ID_OPT = "service-id"
11
+ SERVICE_FILE_OPT = "service-file"
12
+ SERVICE_TYPE_OPT = "service-type"
13
+ PORT_OPT = "port"
14
+ POLICY_OPT = "policy"
15
+
16
+ DOCKER_RUN_TEMPLATE_OPT = "docker-run-template"
17
+ DOCKER_RUN_OPT = "docker-run-opts"
18
+ DOCKER_BUILD_TEMPLATE_OPT = "docker-build-template"
19
+
20
+ DEF_POLICY = "urn:ivcap:policy:ivcap.base.metadata"
21
+ DEF_PORT = 8000
22
+
23
+ DOCKER_BUILD_TEMPLATE = """
24
+ docker buildx build
25
+ -t #DOCKER_NAME#
26
+ --platform linux/#ARCH#
27
+ --build-arg VERSION=#VERSION#
28
+ --build-arg BUILD_PLATFORM=linux/#ARCH#
29
+ -f #PROJECT_DIR#/#DOCKERFILE#
30
+ --load #PROJECT_DIR#
31
+ """
32
+
33
+ DOCKER_LAMBDA_RUN_TEMPLATE = """
34
+ docker run -it
35
+ -p #PORT#:#PORT#
36
+ --platform=linux/#ARCH#
37
+ --rm \
38
+ #NAME#_#ARCH#:#TAG#
39
+ """
40
+
41
+ DOCKER_BATCH_RUN_TEMPLATE = """
42
+ docker run -it
43
+ --platform=linux/#ARCH#
44
+ -v #PROJECT_DIR#:/data
45
+ --rm \
46
+ #NAME#_#ARCH#:#TAG#
47
+ """
@@ -12,34 +12,9 @@ from typing import Dict, List, Optional
12
12
  from pydantic import BaseModel, Field
13
13
  import subprocess
14
14
 
15
+ from .constants import DEF_PORT, DOCKER_BATCH_RUN_TEMPLATE, DOCKER_BUILD_TEMPLATE, DOCKER_BUILD_TEMPLATE_OPT, DOCKER_LAMBDA_RUN_TEMPLATE, DOCKER_RUN_OPT, DOCKER_RUN_TEMPLATE_OPT, PLUGIN_NAME, SERVICE_TYPE_OPT
15
16
  from .util import command_exists, get_name, get_version
16
17
 
17
- DOCKER_BUILD_TEMPLATE = """
18
- docker buildx build
19
- -t #DOCKER_NAME#
20
- --platform linux/#ARCH#
21
- --build-arg VERSION=#VERSION#
22
- --build-arg BUILD_PLATFORM=linux/#ARCH#
23
- -f #PROJECT_DIR#/#DOCKERFILE#
24
- --load #PROJECT_DIR#
25
- """
26
-
27
- DOCKER_LAMBDA_RUN_TEMPLATE = """
28
- docker run -it
29
- -p #PORT#:#PORT#
30
- --platform=linux/#ARCH#
31
- --rm \
32
- #NAME#_#ARCH#:#TAG#
33
- """
34
-
35
- DOCKER_BATCH_RUN_TEMPLATE = """
36
- docker run -it
37
- --platform=linux/#ARCH#
38
- -v #PROJECT_DIR#:/data
39
- --rm \
40
- #NAME#_#ARCH#:#TAG#
41
- """
42
-
43
18
  class DockerConfig(BaseModel):
44
19
  name: Optional[str] = Field(None)
45
20
  tag: Optional[str] = Field(None)
@@ -53,8 +28,8 @@ class DockerConfig(BaseModel):
53
28
  return f"{self.name}_{self.arch}:{self.tag}"
54
29
 
55
30
  def from_build_template(self, data: dict) -> str:
56
- pdata = data.get("tool", {}).get("poetry-plugin-ivcap", {})
57
- template = pdata.get("docker-build-template", DOCKER_BUILD_TEMPLATE).strip()
31
+ pdata = data.get("tool", {}).get(PLUGIN_NAME, {})
32
+ template = pdata.get(DOCKER_BUILD_TEMPLATE_OPT, DOCKER_BUILD_TEMPLATE).strip()
58
33
  t = template.strip()\
59
34
  .replace("#DOCKER_NAME#", self.docker_name)\
60
35
  .replace("#NAME#", self.name)\
@@ -67,35 +42,29 @@ class DockerConfig(BaseModel):
67
42
  return t
68
43
 
69
44
  def from_run_template(self, data, args, line) -> List[any]:
70
- pdata = data.get("tool", {}).get("poetry-plugin-ivcap", {})
71
- template = pdata.get("docker-run-template")
45
+ pdata = data.get("tool", {}).get(PLUGIN_NAME, {})
46
+ template = pdata.get(DOCKER_RUN_TEMPLATE_OPT)
47
+ smode = pdata.get(SERVICE_TYPE_OPT)
48
+ if smode is None:
49
+ line(f"<error>ERROR: 'service-type' is not defined in [{PLUGIN_NAME}]</error>")
50
+ sys.exit(1)
72
51
  if template is None:
73
- smode = pdata.get("service-type")
74
- if smode is None:
75
- line("<error>ERROR: 'service-type' is not defined in [poetry-plugin-ivcap]</error>")
76
- sys.exit(1)
77
52
  if smode == "lambda":
78
53
  template = DOCKER_LAMBDA_RUN_TEMPLATE
79
54
  elif smode == "batch":
80
55
  template = DOCKER_BATCH_RUN_TEMPLATE
81
56
  else:
82
- line(f"<error>ERROR: Unknown service type '{smode}' in [poetry-plugin-ivcap]</error>")
57
+ line(f"<error>ERROR: Unknown service type '{smode}' in [{PLUGIN_NAME}]</error>")
83
58
  sys.exit(1)
84
59
 
85
- opts = pdata.get("docker-run-opts", [])
60
+ opts = pdata.get(DOCKER_RUN_OPT, [])
86
61
  port = get_port_value(args)
87
62
  port_in_args = True
88
63
  if not port:
89
64
  port = get_port_value(opts)
90
65
  if not port:
91
66
  port_in_args = False
92
- port = str(pdata.get("port", 8000))
93
-
94
- # elif opts.get('port') is not None:
95
- # opts['port'] = opts.get('port')
96
- # elif '--port' in template:
97
- # # If the template has a port but no port is provided, use a default
98
- # opts['port'] = '8000'
67
+ port = str(pdata.get("port", DEF_PORT))
99
68
 
100
69
  t = template.strip()\
101
70
  .replace("#NAME#", self.name)\
@@ -105,11 +74,6 @@ class DockerConfig(BaseModel):
105
74
  .replace("#VERSION#", self.version)\
106
75
  .replace("#PROJECT_DIR#", self.project_dir)
107
76
 
108
- # for key, value in opts.items():
109
- # if key != "port":
110
- # t = t.replace(f"#{key.upper()}#", str(value))
111
-
112
-
113
77
  cmd = t.split()
114
78
  cmd.extend(opts)
115
79
  cmd.extend(args)
@@ -146,7 +110,7 @@ def docker_run(data: dict, args, line) -> None:
146
110
  def docker_cfg(data: dict, line, arch = None) -> DockerConfig:
147
111
  name = get_name(data)
148
112
 
149
- pdata = data.get("tool", {}).get("poetry-plugin-ivcap", {})
113
+ pdata = data.get("tool", {}).get(PLUGIN_NAME, {})
150
114
  config = DockerConfig(name=name, **pdata.get("docker", {}))
151
115
  if arch:
152
116
  # override architecture if provided
@@ -11,8 +11,10 @@ import tempfile
11
11
  import uuid
12
12
  import humanize
13
13
 
14
+ from .constants import DEF_POLICY, PLUGIN_NAME, POLICY_OPT, SERVICE_FILE_OPT, SERVICE_ID_OPT
15
+
14
16
  from .docker import docker_cfg, docker_build, docker_push
15
- from .util import command_exists, execute_subprocess_and_capture_output, get_name, string_to_number
17
+ from .util import command_exists, get_name, string_to_number
16
18
 
17
19
  def docker_publish(data, line):
18
20
  check_ivcap_cmd(line)
@@ -29,11 +31,11 @@ def docker_publish(data, line):
29
31
 
30
32
  def service_register(data, line):
31
33
  check_ivcap_cmd(line)
32
- config = data.get("tool", {}).get("poetry-plugin-ivcap", {})
34
+ config = data.get("tool", {}).get(PLUGIN_NAME, {})
33
35
 
34
- service = config.get("service-file")
36
+ service = config.get(SERVICE_FILE_OPT)
35
37
  if not service:
36
- line("<error>Missing 'service-file' in [tool.poetry-plugin-ivcap]</error>")
38
+ line(f"<error>Missing '{SERVICE_FILE_OPT}' in [tool.{PLUGIN_NAME}]</error>")
37
39
  return
38
40
 
39
41
  dcfg = docker_cfg(data, line, "amd64")
@@ -74,11 +76,11 @@ def service_register(data, line):
74
76
 
75
77
  def tool_register(data, line):
76
78
  check_ivcap_cmd(line)
77
- config = data.get("tool", {}).get("poetry-plugin-ivcap", {})
79
+ config = data.get("tool", {}).get(PLUGIN_NAME, {})
78
80
 
79
81
  service = config.get("service-file")
80
82
  if not service:
81
- line("<error>Missing 'service-file' in [tool.poetry-plugin-ivcap]</error>")
83
+ line(f"<error>Missing 'service-file' in [tool.{PLUGIN_NAME}]</error>")
82
84
  return
83
85
 
84
86
  cmd = ["poetry", "run", "python", service, "--print-tool-description"]
@@ -109,7 +111,7 @@ def tool_register(data, line):
109
111
  os.remove(tmp_path)
110
112
 
111
113
  def get_service_id(data, is_silent, line):
112
- service_id = data.get("tool", {}).get("poetry-plugin-ivcap", {}).get("service-id")
114
+ service_id = data.get("tool", {}).get(PLUGIN_NAME, {}).get(SERVICE_ID_OPT)
113
115
  if not service_id:
114
116
  service_id = create_service_id(data, is_silent, line)
115
117
  return service_id
@@ -122,9 +124,9 @@ def create_service_id(data, is_silent, line):
122
124
  return f"urn:ivcap:service:{id}"
123
125
 
124
126
  def get_policy(data, line):
125
- policy = data.get("tool", {}).get("poetry-plugin-ivcap", {}).get("policy")
127
+ policy = data.get("tool", {}).get(PLUGIN_NAME, {}).get(POLICY_OPT)
126
128
  if not policy:
127
- policy = "urn:ivcap:policy:ivcap.open.metadata"
129
+ policy = DEF_POLICY
128
130
  return policy
129
131
 
130
132
  def get_account_id(data, line, is_silent=False):
@@ -10,6 +10,7 @@ from cleo.helpers import argument, option
10
10
  import subprocess
11
11
  from importlib.metadata import version
12
12
 
13
+ from poetry_plugin_ivcap.constants import DOCKER_BUILD_TEMPLATE_OPT, DOCKER_RUN_TEMPLATE_OPT, PLUGIN_CMD, PLUGIN_NAME, PORT_OPT, SERVICE_FILE_OPT, SERVICE_ID_OPT, SERVICE_TYPE_OPT
13
14
  from poetry_plugin_ivcap.util import get_version
14
15
 
15
16
  from .ivcap import create_service_id, get_service_id, service_register, tool_register
@@ -18,8 +19,8 @@ from .ivcap import docker_publish
18
19
 
19
20
  class IvcapCommand(Command):
20
21
  name = "ivcap"
21
- description = "IVCAP plugin `poetry ivcap <subcommand>`"
22
- help = """\
22
+ description = f"IVCAP plugin `poetry {PLUGIN_CMD} <subcommand>`"
23
+ help = f"""\
23
24
 
24
25
  IVCAP plugin
25
26
 
@@ -34,19 +35,21 @@ Available subcommands:
34
35
  create-service-id Create a unique service ID for the service
35
36
  get-service-id Return the service ID for the service
36
37
  tool-register Register the service as an AI Tool with IVCAP
38
+ version Print the version of this plugin
37
39
 
38
40
  Example:
39
- poetry ivcap run -- --port 8080
41
+ poetry {PLUGIN_CMD} run -- --port 8080
40
42
 
41
43
  Configurable options in pyproject.toml:
42
44
 
43
- [tool.poetry-plugin-ivcap]
44
- service-file = "service.py" # The Python file that implements the service
45
- service-file = "service.py"
46
- service-id = "urn:ivcap:service:ac158a1f-dfb4-5dac-bf2e-9bf15e0f2cc7" # A unique identifier for the service
45
+ [tool.{PLUGIN_NAME}]
46
+ {SERVICE_FILE_OPT} = "service.py" # The Python file that implements the service
47
+ {SERVICE_ID_OPT} = "urn:ivcap:service:ac158a1f-dfb4-5dac-bf2e-9bf15e0f2cc7" # A unique identifier for the service
48
+ {SERVICE_TYPE_OPT} = "lambda
47
49
 
48
- docker-build-template = "docker buildx build -t #DOCKER_NAME# ."
49
- docker-run-template = "docker run -rm -p #PORT#:#PORT#"
50
+ # Optional
51
+ {DOCKER_BUILD_TEMPLATE_OPT} = "docker buildx build -t #DOCKER_NAME# ."
52
+ {DOCKER_RUN_TEMPLATE_OPT} = "docker run -rm -p #PORT#:#PORT#"
50
53
  """
51
54
  arguments = [
52
55
  argument("subcommand", optional=True, description="Subcommand: run, deploy, etc."),
@@ -64,7 +67,7 @@ Configurable options in pyproject.toml:
64
67
  sub = self.argument("subcommand")
65
68
  if sub == "version":
66
69
  #v = poetry.get_plugin('ivcap').version
67
- v = version("poetry-plugin-ivcap")
70
+ v = version(PLUGIN_NAME)
68
71
  print(f"IVCAP plugin (version {v})")
69
72
  return
70
73
 
@@ -99,15 +102,15 @@ Configurable options in pyproject.toml:
99
102
  print(self.help)
100
103
 
101
104
  def run_service(self, data, args, line):
102
- config = data.get("tool", {}).get("poetry-plugin-ivcap", {})
105
+ config = data.get("tool", {}).get(PLUGIN_NAME, {})
103
106
 
104
- service = config.get("service-file")
107
+ service = config.get(SERVICE_FILE_OPT)
105
108
  if not service:
106
- self.line("<error>Missing 'service-file' in [tool.poetry-plugin-ivcap]</error>")
109
+ self.line(f"<error>Missing '{SERVICE_FILE_OPT}' in [tool.{PLUGIN_NAME}]</error>")
107
110
  return
108
111
 
109
112
  if not '--port' in args:
110
- port = config.get("port")
113
+ port = config.get(PORT_OPT)
111
114
  if port:
112
115
  args.extend(["--port", str(port)])
113
116
 
@@ -121,4 +124,4 @@ Configurable options in pyproject.toml:
121
124
 
122
125
  class IvcapPlugin(ApplicationPlugin):
123
126
  def activate(self, application):
124
- application.command_loader.register_factory("ivcap", lambda: IvcapCommand())
127
+ application.command_loader.register_factory(PLUGIN_CMD, lambda: IvcapCommand())
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "poetry-plugin-ivcap"
3
- version = "0.2.6"
3
+ version = "0.2.8"
4
4
  description = "A custom Poetry command for IVCAP deployments"
5
5
  authors = ["Max Ott <max.ott@csiro.au>"]
6
6
  license = "MIT"