donkey-llms-watsonx 0.1.0__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.
@@ -0,0 +1,85 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ #IDE
10
+ .DS_Store
11
+ .idea
12
+ .vscode
13
+
14
+ # Distribution / packaging
15
+ .Python
16
+ build/
17
+ develop-eggs/
18
+ dist/
19
+ downloads/
20
+ eggs/
21
+ .eggs/
22
+ lib/
23
+ lib64/
24
+ parts/
25
+ sdist/
26
+ var/
27
+ wheels/
28
+ share/python-wheels/
29
+ *.egg-info/
30
+ .installed.cfg
31
+ *.egg
32
+ MANIFEST
33
+
34
+ # PyInstaller
35
+ # Usually these files are written by a python script from a template
36
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
37
+ *.manifest
38
+ *.spec
39
+
40
+ # Installer logs
41
+ pip-log.txt
42
+ pip-delete-this-directory.txt
43
+
44
+ # Unit test / coverage reports
45
+ htmlcov/
46
+ .tox/
47
+ .nox/
48
+ .coverage
49
+ .coverage.*
50
+ .cache
51
+ nosetests.xml
52
+ coverage.xml
53
+ *.cover
54
+ *.py,cover
55
+ .hypothesis/
56
+ .pytest_cache/
57
+ cover/
58
+
59
+ # Mkdocs documentation
60
+ docs/_build/
61
+ docs/api_reference/site/
62
+
63
+ # Ruff
64
+ .ruff_cache/
65
+
66
+ # PyBuilder
67
+ .pybuilder/
68
+ target/
69
+
70
+ # Jupyter Notebook
71
+ .ipynb_checkpoints
72
+
73
+ # pyenv
74
+ # For a library or package, you might want to ignore these files since the code is
75
+ # intended to run in multiple environments; otherwise, check them in:
76
+ .python-version
77
+
78
+ # Environments
79
+ .env
80
+ .venv
81
+ env/
82
+ venv/
83
+ ENV/
84
+ env.bak/
85
+ venv.bak/
@@ -0,0 +1,22 @@
1
+ Metadata-Version: 2.4
2
+ Name: donkey-llms-watsonx
3
+ Version: 0.1.0
4
+ Summary: donkey llms watsonx integration
5
+ Author-email: Leonardo Furnielis <leonardofurnielis@outlook.com>
6
+ License: Apache-2.0
7
+ Requires-Python: <3.14,>=3.11
8
+ Requires-Dist: donkey-core<0.2.0,>=0.1.0
9
+ Requires-Dist: ibm-watsonx-ai<1.6.0,>=1.5.5
10
+ Provides-Extra: dev
11
+ Requires-Dist: pytest-asyncio<2.0.0,>=1.4.0; extra == 'dev'
12
+ Requires-Dist: pytest<10.0.0,>=9.1.1; extra == 'dev'
13
+ Requires-Dist: ruff<0.16.0,>=0.15.20; extra == 'dev'
14
+ Description-Content-Type: text/markdown
15
+
16
+ # Donkey llms integration - watsonx
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ pip install donkey-llms-watsonx
22
+ ```
@@ -0,0 +1,7 @@
1
+ # Donkey llms integration - watsonx
2
+
3
+ ## Installation
4
+
5
+ ```bash
6
+ pip install donkey-llms-watsonx
7
+ ```
@@ -0,0 +1,3 @@
1
+ from donkey.llms.watsonx.base import WatsonxLLM
2
+
3
+ __all__ = ["WatsonxLLM"]
@@ -0,0 +1,121 @@
1
+ from typing import Any
2
+
3
+ from donkey.core.bridge.pydantic import Field, SecretStr, field_validator
4
+ from donkey.core.llms import BaseLLM, ChatMessage, ChatResponse, CompletionResponse
5
+ from donkey.core.toolkit import validate_enum
6
+ from donkey.llms.watsonx.supporting_classes.enums import Region
7
+
8
+
9
+ class WatsonxLLM(BaseLLM):
10
+ """
11
+ A wrapper class for interacting with a IBM watsonx.ai large language models (LLMs).
12
+ For more information, see [here](https://dataplatform.cloud.ibm.com/docs/content/wsj/analyze-data/fm-models.html?context=wx&audience=wdp).
13
+
14
+
15
+ Attributes:
16
+ model (str): The identifier of the LLM model to use (e.g., "openai/gpt-oss-120b", "meta-llama/llama-3-3-70b-instruct").
17
+ api_key (str): API key used for authenticating with the LLM provider.
18
+ region (str, optional): The region where watsonx.ai is hosted when using IBM Cloud.
19
+ Defaults to `us-south`.
20
+ project_id (str, optional): The project ID in watsonx.ai.
21
+ space_id (str, optional): The space ID in watsonx.ai.
22
+ additional_kwargs (dict[str, Any], optional): A dictionary of additional parameters passed
23
+ to the LLM during completion. This allows customization of the request beyond
24
+ the standard parameters.
25
+ callback_manager: (PromptMonitor, optional): The callback manager is used for observability.
26
+
27
+ Example:
28
+ ```python
29
+ from donkey.llms.watsonx import WatsonxLLM
30
+
31
+ llm = WatsonxLLM(model="openai/gpt-oss-120b", api_key="your_api_key_here")
32
+ ```
33
+ """
34
+
35
+ model_config = {
36
+ "validate_assignment": False,
37
+ }
38
+
39
+ model: str
40
+ api_key: SecretStr
41
+ region: str = Region.US_SOUTH
42
+ project_id: str | None = Field(default=None)
43
+ space_id: str | None = Field(default=None)
44
+ params: dict[str, Any] = Field(default_factory=dict)
45
+ additional_kwargs: dict[str, Any] = Field(default_factory=dict)
46
+
47
+ @field_validator("region")
48
+ def _validate_region(cls, v):
49
+ validate_enum(el=v, el_name="region", expected_enum=Region)
50
+ return v
51
+
52
+ def model_post_init(self, __context): # noqa: PYI063
53
+ from ibm_watsonx_ai import Credentials
54
+ from ibm_watsonx_ai.foundation_models import ModelInference
55
+
56
+ self.region = Region.from_value(self.region)
57
+
58
+ if (not (self.project_id or self.space_id)) or (
59
+ self.project_id and self.space_id
60
+ ):
61
+ raise ValueError(
62
+ "Invalid configuration: 'project_id' or 'space_id' must be provided. Not both."
63
+ )
64
+
65
+ self._model_inference = ModelInference(
66
+ **self.additional_kwargs,
67
+ model_id=self.model,
68
+ credentials=Credentials(
69
+ api_key=self.api_key.get_secret_value(),
70
+ url=self.region.watsonx,
71
+ ),
72
+ project_id=self.project_id,
73
+ space_id=self.space_id,
74
+ )
75
+
76
+ def _completion(
77
+ self,
78
+ prompt: str,
79
+ guardrails: bool = False,
80
+ params: dict[str, Any] = {},
81
+ **kwargs: Any,
82
+ ) -> CompletionResponse:
83
+ """Creates a completion for the provided prompt and parameters. Using OpenAI's standard endpoint (/completions)."""
84
+ response = self._model_inference.generate(
85
+ **kwargs,
86
+ prompt=prompt,
87
+ guardrails=guardrails,
88
+ params={**self.params, **params},
89
+ )
90
+
91
+ return CompletionResponse(
92
+ text=response["results"][0].get("generated_text"),
93
+ input_token_count=response["results"][0].get("input_token_count"),
94
+ generated_token_count=response["results"][0].get("generated_token_count"),
95
+ raw=response,
96
+ )
97
+
98
+ def _chat_completion(
99
+ self,
100
+ messages: list[ChatMessage | dict],
101
+ params: dict[str, Any] = {},
102
+ **kwargs: Any,
103
+ ) -> ChatResponse:
104
+ """Creates a chat completion for LLM. Using OpenAI's standard endpoint (/chat/completions)."""
105
+ input_messages_dict = [
106
+ ChatMessage.model_validate(message).to_dict() for message in messages
107
+ ]
108
+
109
+ response = self._model_inference.chat(
110
+ **kwargs,
111
+ messages=input_messages_dict,
112
+ params={**self.params, **params},
113
+ )
114
+ message_dict = response["choices"][0]["message"]
115
+
116
+ return ChatResponse(
117
+ message=ChatMessage(
118
+ role=message_dict.get("role"), content=message_dict.get("content", None)
119
+ ),
120
+ raw=response,
121
+ )
@@ -0,0 +1,64 @@
1
+ from typing import Any
2
+
3
+ REGION_CONFIG: dict = {
4
+ "au-syd": {
5
+ "watsonx": "https://au-syd.ml.cloud.ibm.com",
6
+ },
7
+ "aws-ap-south": {
8
+ "watsonx": "https://ap-south-1.aws.wxai.ibm.com",
9
+ },
10
+ "eu-de": {
11
+ "watsonx": "https://eu-de.ml.cloud.ibm.com",
12
+ },
13
+ "us-south": {
14
+ "watsonx": "https://us-south.ml.cloud.ibm.com",
15
+ },
16
+ }
17
+
18
+
19
+ class RegionValue(str):
20
+ @property
21
+ def watsonx(self) -> str:
22
+ return REGION_CONFIG[self]["watsonx"]
23
+
24
+
25
+ class Region:
26
+ """
27
+ Supported IBM watsonx.governance regions.
28
+
29
+ Defines the available regions where watsonx.governance SaaS
30
+ services are deployed.
31
+
32
+ Attributes:
33
+ AU_SYD (str): "au-syd".
34
+ AWS_AP_SOUTH (str): "aws-ap-south".
35
+ EU_DE (str): "eu-de".
36
+ US_SOUTH (str): "us-south".
37
+ """
38
+
39
+ AU_SYD = RegionValue("au-syd")
40
+ AWS_AP_SOUTH = RegionValue("aws-ap-south")
41
+ EU_DE = RegionValue("eu-de")
42
+ US_SOUTH = RegionValue("us-south")
43
+
44
+ @classmethod
45
+ def from_value(cls, value: Any) -> "RegionValue":
46
+ if value is None:
47
+ return cls.US_SOUTH
48
+
49
+ if isinstance(value, RegionValue):
50
+ return value
51
+
52
+ if isinstance(value, str):
53
+ value = value.lower()
54
+
55
+ for region in (getattr(cls, name) for name in vars(cls) if name.isupper()):
56
+ if region == value:
57
+ return region
58
+
59
+ raise ValueError("Invalid value for Region: '{}'.".format(value))
60
+
61
+ raise TypeError(
62
+ f"Invalid type for Region. "
63
+ f"Expected str or Region, but received {type(value).__name__}."
64
+ )
@@ -0,0 +1,29 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "donkey-llms-watsonx"
7
+ version = "0.1.0"
8
+ description = "donkey llms watsonx integration"
9
+ authors = [{ name = "Leonardo Furnielis", email = "leonardofurnielis@outlook.com" }]
10
+ license = { text = "Apache-2.0" }
11
+ readme = "README.md"
12
+ requires-python = ">=3.11,<3.14"
13
+ dependencies = [
14
+ "ibm-watsonx-ai>=1.5.5,<1.6.0",
15
+ "donkey-core>=0.1.0,<0.2.0",
16
+ ]
17
+
18
+ [tool.hatch.build.targets.sdist]
19
+ include = ["donkey/"]
20
+
21
+ [tool.hatch.build.targets.wheel]
22
+ include = ["donkey/"]
23
+
24
+ [project.optional-dependencies]
25
+ dev = [
26
+ "pytest>=9.1.1,<10.0.0",
27
+ "pytest-asyncio>=1.4.0,<2.0.0",
28
+ "ruff>=0.15.20,<0.16.0",
29
+ ]