Skip to content

Commit a443ad5

Browse files
committed
Add demo-specific changes
1 parent 0a50062 commit a443ad5

11 files changed

Lines changed: 230 additions & 14 deletions

File tree

‎Dockerfile‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ USER splunk
2323

2424
WORKDIR /tmp/sdk
2525

26-
RUN /bin/bash -c "LD_LIBRARY_PATH=/opt/splunk/lib /opt/splunk/bin/python3.13 -m pip install '.[openai]' --target=/splunklib-deps"
26+
RUN /bin/bash -c "LD_LIBRARY_PATH=/opt/splunk/lib /opt/splunk/bin/python3.13 -m pip install '.[openai,bedrock]' --target=/splunklib-deps"
2727

2828
USER ${ANSIBLE_USER}
2929
WORKDIR /opt/splunk

‎Makefile‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,3 +116,7 @@ docker-splunk-restart:
116116
.PHONY: docker-tail-python-log
117117
docker-tail-python-log:
118118
docker exec -it $(CONTAINER_NAME) sudo tail $(SPLUNK_HOME)/var/log/splunk/python.log
119+
120+
.PHONY: bedrock-login
121+
bedrock-login:
122+
./scripts/bedrock-login.sh

‎compose.yml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ services:
1111
- SPLUNK_HEC_TOKEN=11111111-1111-1111-1111-1111111111113
1212
- SPLUNK_PASSWORD=changed!
1313
- SPLUNK_APPS_URL=https://github.com/splunk/sdk-app-collection/releases/latest/download/sdkappcollection.tgz
14+
- TZ=Europe/Warsaw
1415
ports:
1516
- "8000:8000"
1617
- "8088:8088"
@@ -33,6 +34,7 @@ services:
3334
- "./examples/ai_custom_search_app:/opt/splunk/etc/apps/ai_custom_search_app"
3435
- "./examples/ai_custom_alert_app:/opt/splunk/etc/apps/ai_custom_alert_app"
3536
- "./examples/ai_modinput_app:/opt/splunk/etc/apps/ai_modinput_app"
37+
- "~/Projects/mclaren-demo-app:/opt/splunk/etc/apps/mclaren_demo_app"
3638

3739
- "./splunklib:/opt/splunk/etc/apps/eventing_app/bin/splunklib"
3840
- "./splunklib:/opt/splunk/etc/apps/generating_app/bin/splunklib"
@@ -44,6 +46,9 @@ services:
4446
- "./splunklib:/opt/splunk/etc/apps/ai_custom_search_app/bin/lib/splunklib"
4547
- "./splunklib:/opt/splunk/etc/apps/ai_custom_alert_app/bin/lib/splunklib"
4648
- "./splunklib:/opt/splunk/etc/apps/ai_modinput_app/bin/lib/splunklib"
49+
- "./splunklib:/opt/splunk/etc/apps/mclaren_demo_app/bin/lib/splunklib"
4750

4851
- "./tests:/opt/splunk/etc/apps/ai_agentic_test_app/bin/lib/tests"
4952
- "./tests:/opt/splunk/etc/apps/ai_agentic_test_local_tools_app/bin/lib/tests"
53+
54+
- "~/.aws:/home/splunk/.aws:ro"

‎examples/ai_modinput_app/bin/agentic_weather.py‎

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,6 @@
2020
from _collections_abc import dict_items
2121
from typing import final, override
2222

23-
from splunklib.ai.messages import AIMessage, ContentBlock, TextBlock
24-
2523
# ! NOTE: This insert is only needed for splunk-sdk-python CI/CD to work.
2624
# ! Remove this if you're modifying this example locally.
2725
sys.path.insert(0, "/splunklib-deps")
@@ -33,6 +31,7 @@
3331

3432
from splunklib.ai import OpenAIModel
3533
from splunklib.ai.agent import Agent
34+
from splunklib.ai.messages import AIMessage, ContentBlock, TextBlock
3635
from splunklib.modularinput.argument import Argument
3736
from splunklib.modularinput.event import Event
3837
from splunklib.modularinput.event_writer import EventWriter

‎pyproject.toml‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ version = "3.0.1a0"
1212
description = "Splunk Software Development Kit for Python"
1313
readme = "README.md"
1414
requires-python = ">=3.13"
15-
license = { text = "Apache-2.0" }
16-
authors = [{ name = "Splunk, Inc.", email = "devinfo@splunk.com" }]
15+
license = "Apache-2.0"
16+
authors = [{ name = "Splunk, Inc.", email = "devsupport@splunk.com" }]
1717
keywords = ["splunk", "sdk"]
1818
classifiers = [
1919
"Programming Language :: Python :: 3",
@@ -35,6 +35,7 @@ dependencies = []
3535
compat = ["six>=1.17.0"]
3636
ai = ["httpx==0.28.1", "langchain>=1.2.18", "mcp>=1.27.1", "pydantic>=2.13.4"]
3737
anthropic = ["splunk-sdk[ai]>=3.0.0", "langchain-anthropic>=1.4.3"]
38+
bedrock = ["splunk-sdk[ai]>=3.0.0", "langchain-aws>=0.2.0"]
3839
openai = ["splunk-sdk[ai]>=3.0.0", "langchain-openai>=1.2.1"]
3940
google = [
4041
"splunk-sdk[ai]>=3.0.0",
@@ -45,7 +46,7 @@ google = [
4546
# Treat the same as NPM's `devDependencies`
4647
[dependency-groups]
4748
test = [
48-
"splunk-sdk[openai, anthropic, google]>=3.0.0",
49+
"splunk-sdk[openai, anthropic, google, bedrock]>=3.0.0",
4950
"pytest>=9.0.3",
5051
"pytest-cov>=7.1.0",
5152
"pytest-asyncio>=1.3.0",

‎scripts/bedrock-login.sh‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
PROFILE="${1:-ssc-ci-cd_bedrock-inference-role}"
5+
CONTAINER="${2:-splunk}"
6+
LAUNCH_CONF="/opt/splunk/etc/splunk-launch.conf"
7+
8+
echo "Fetching credentials for profile: $PROFILE"
9+
CREDS=$(dev-login aws credential-process --profile "$PROFILE")
10+
11+
KEY=$(echo "$CREDS" | python3 -c "import sys,json; print(json.load(sys.stdin)['AccessKeyId'])")
12+
SECRET=$(echo "$CREDS" | python3 -c "import sys,json; print(json.load(sys.stdin)['SecretAccessKey'])")
13+
TOKEN=$(echo "$CREDS" | python3 -c "import sys,json; print(json.load(sys.stdin)['SessionToken'])")
14+
EXPIRY=$(echo "$CREDS" | python3 -c "import sys,json; print(json.load(sys.stdin)['Expiration'])")
15+
16+
docker exec "$CONTAINER" sudo sh -c "
17+
sed -i '/AWS_ACCESS_KEY_ID=/d;/AWS_SECRET_ACCESS_KEY=/d;/AWS_SESSION_TOKEN=/d' $LAUNCH_CONF 2>/dev/null || true
18+
printf '\nAWS_ACCESS_KEY_ID=$KEY\nAWS_SECRET_ACCESS_KEY=$SECRET\nAWS_SESSION_TOKEN=$TOKEN\n' >> $LAUNCH_CONF
19+
"
20+
21+
echo "Credentials injected (expire: $EXPIRY)"
22+
echo "Restarting Splunk to apply..."
23+
docker restart "$CONTAINER"

‎splunklib/ai/__init__.py‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
raise ImportError("Python 3.13 or newer is required to use this module")
1919

2020
from splunklib.ai.agent import Agent
21-
from splunklib.ai.model import AnthropicModel, GoogleModel, OpenAIModel
21+
from splunklib.ai.model import AnthropicModel, BedrockModel, GoogleModel, OpenAIModel
2222
from splunklib.ai.security import (
2323
create_structured_prompt,
2424
detect_injection,
@@ -28,6 +28,7 @@
2828
__all__ = [
2929
"Agent",
3030
"AnthropicModel",
31+
"BedrockModel",
3132
"GoogleModel",
3233
"OpenAIModel",
3334
"create_structured_prompt",

‎splunklib/ai/agent.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ async def _start_agent(self) -> AsyncGenerator[Self]:
195195
)
196196

197197
splunk_username = await asyncio.to_thread(lambda: _get_splunk_username(self._service))
198-
_validate_agent_privileges(splunk_username)
198+
# _validate_agent_privileges(splunk_username)
199199

200200
self.logger.debug(f"Creating agent {self.name=}; {self.trace_id=}")
201201

‎splunklib/ai/engines/langchain.py‎

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,13 @@
119119
subagent_middleware,
120120
tool_middleware,
121121
)
122-
from splunklib.ai.model import AnthropicModel, GoogleModel, OpenAIModel, PredefinedModel
122+
from splunklib.ai.model import (
123+
AnthropicModel,
124+
BedrockModel,
125+
GoogleModel,
126+
OpenAIModel,
127+
PredefinedModel,
128+
)
123129
from splunklib.ai.security import create_structured_prompt
124130
from splunklib.ai.structured_output import (
125131
StructuredOutputGenerationException,
@@ -1830,6 +1836,29 @@ def _create_langchain_model(model: PredefinedModel) -> BaseChatModel:
18301836
+ "# or if using uv:\n"
18311837
+ "uv add splunk-sdk[anthropic]"
18321838
)
1839+
case BedrockModel():
1840+
try:
1841+
from langchain_aws import ChatBedrockConverse
1842+
1843+
kwargs = {
1844+
"model": model.model,
1845+
"provider": "anthropic",
1846+
}
1847+
if model.base_model_id:
1848+
kwargs["base_model_id"] = model.base_model_id # type: ignore[assignment]
1849+
if model.aws_region is not None:
1850+
kwargs["region_name"] = model.aws_region # type: ignore[assignment]
1851+
if model.temperature is not None:
1852+
kwargs["temperature"] = model.temperature # type: ignore[assignment]
1853+
return ChatBedrockConverse(**kwargs)
1854+
except ImportError:
1855+
raise ImportError(
1856+
"AWS Bedrock support is not installed.\n"
1857+
+ "To enable Bedrock models, install the optional extra:\n"
1858+
+ 'pip install "splunk-sdk[bedrock]"\n'
1859+
+ "# or if using uv:\n"
1860+
+ "uv add splunk-sdk[bedrock]"
1861+
)
18331862
case GoogleModel():
18341863
try:
18351864
from langchain_google_genai import ChatGoogleGenerativeAI

‎splunklib/ai/model.py‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,24 @@ class AnthropicModel(PredefinedModel):
6767
temperature: float | None = None
6868

6969

70+
@dataclass(frozen=True, kw_only=True)
71+
class BedrockModel(PredefinedModel):
72+
"""Anthropic model served via AWS Bedrock using ``langchain-aws``.
73+
74+
Requires ``langchain-aws`` and ``boto3`` at runtime.
75+
Credentials are resolved via the standard AWS credential chain.
76+
77+
``base_model_id`` is required when ``model`` is an ARN — it tells
78+
``ChatBedrockConverse`` the underlying model family so it can skip
79+
the ``GetInferenceProfile`` API call.
80+
"""
81+
82+
model: str
83+
base_model_id: str = ""
84+
aws_region: str | None = None
85+
temperature: float | None = None
86+
87+
7088
@dataclass(frozen=True, kw_only=True)
7189
class GoogleModel(PredefinedModel):
7290
"""Predefined Google Model
@@ -100,6 +118,7 @@ class GoogleModel(PredefinedModel):
100118

101119
__all__ = [
102120
"AnthropicModel",
121+
"BedrockModel",
103122
"GoogleModel",
104123
"OpenAIModel",
105124
"PredefinedModel",

0 commit comments

Comments
 (0)