Skip to content

Commit

Permalink
[community] Add Jenkins tool support.
Browse files Browse the repository at this point in the history
This PR are used to support Jenkins API to cover below feature,

* Create Jenkin Job.
* Delete Jenkin Job.
* Run the Jenkin job.
* Get Job Status.
  • Loading branch information
Amitgb14 authored and aghadge committed Jan 27, 2025
1 parent dbb6b7b commit 39cc487
Show file tree
Hide file tree
Showing 5 changed files with 421 additions and 0 deletions.
204 changes: 204 additions & 0 deletions docs/docs/integrations/tools/jenkins.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Jenkins\n",
"\n",
"This notebook, go over how to use Jenkins.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Overview\n",
"Jenkins integration are provide more power in CI/CD pipelines. Execute and control the pipline handling with AI.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Setup\n",
"First make sure that you have installed python-jenkins with the command below:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"%pip install --upgrade --quiet python-jenkins"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Credentials\n",
"Before start using Jenkins, first setup or get authorization to access Jenkins server."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"import getpass\n",
"import os\n",
"\n",
"\n",
"def _set_env(var: str):\n",
" if not os.environ.get(var):\n",
" os.environ[var] = getpass.getpass(f\"{var}: \")\n",
"\n",
"\n",
"_set_env(\"PASSWORD\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Instantiation\n",
"To disable the SSL Verify, set `os.environ[\"PYTHONHTTPSVERIFY\"] = \"0\"`"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from langchain_community.tools.jenkins.tool import JenkinsJobRun\n",
"from langchain_community.utilities.jenkins import JenkinsAPIWrapper\n",
"\n",
"tools = [\n",
" JenkinsJobRun(\n",
" api_wrapper=JenkinsAPIWrapper(\n",
" jenkins_server=\"https://example.com\",\n",
" username=\"admin\",\n",
" password=os.environ[\"PASSWORD\"],\n",
" )\n",
" )\n",
"]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Invocation\n",
"You can now call invoke and pass arguments."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"1. Create the Jenkins job"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"jenkins_job_content = \"\"\n",
"src_file = \"job1.xml\"\n",
"with open(src_file) as fread:\n",
" jenkins_job_content = fread.read()\n",
"tools[0].invoke({\"job\": \"job01\", \"config_xml\": jenkins_job_content, \"action\": \"create\"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"2. Run the Jenkins Job"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tools[0].invoke({\"job\": \"job01\", \"parameters\": {}, \"action\": \"run\"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"3. Get job info"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"resp = tools[0].invoke({\"job\": \"job01\", \"number\": 1, \"action\": \"status\"})\n",
"if not resp[\"inProgress\"]:\n",
" print(resp[\"result\"])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"4. Delete the jenkins job"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"tools[0].invoke({\"job\": \"job01\", \"action\": \"delete\"})"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.1"
},
"vscode": {
"interpreter": {
"hash": "3929050b09828356c9f5ebaf862d05c053d8228eddbc70f990c168e54dd824ba"
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}
5 changes: 5 additions & 0 deletions libs/community/langchain_community/tools/jenkins/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Jenkins Tool."""

from langchain_community.tools.jenkins.tool import JenkinsJobRun

__all__ = ["JenkinsJobRun"]
117 changes: 117 additions & 0 deletions libs/community/langchain_community/tools/jenkins/tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
"""Tool for the Jenkins API"""

from typing import Optional, Type

from langchain_core.callbacks import CallbackManagerForToolRun
from langchain_core.tools import BaseTool
from pydantic import BaseModel, Field

from langchain_community.utilities.jenkins import JenkinsAPIWrapper

class JenkinsSchema(BaseModel):

Check failure on line 11 in libs/community/langchain_community/tools/jenkins/tool.py

View workflow job for this annotation

GitHub Actions / cd libs/community / make lint #3.13

Ruff (I001)

langchain_community/tools/jenkins/tool.py:3:1: I001 Import block is un-sorted or un-formatted

Check failure on line 11 in libs/community/langchain_community/tools/jenkins/tool.py

View workflow job for this annotation

GitHub Actions / cd libs/community / make lint #3.9

Ruff (I001)

langchain_community/tools/jenkins/tool.py:3:1: I001 Import block is un-sorted or un-formatted
"""Input for the Jenkins tool.
Instantiate:
.. code-block:: python
from tools.jenkins.tool import JenkinsJobRun
from tools.jenkins.utility import JenkinsAPIWrapper
tools = [JenkinsJobRun(
api_wrapper=JenkinsAPIWrapper(
jenkins_server="https://jenkinsserver.com",
username="admin",
password=os.environ["PASSWORD"]
)
)]
Invoke directly with args:
.. code-block:: python
# delete jenkins job
tools[0].invoke({'job': "job01", "action": "delete"})
# create jenkins job
jenkins_job_content = ""
src_file = "job1.xml"
with open(src_file) as fread:
jenkins_job_content = fread.read()
tools[0].invoke({'job': "job01", "config_xml": jenkins_job_content,
"action": "create"})
# run the jenkins job
tools[0].invoke({'job': "job01", "parameters": {}, "action": "run"})
# get jenkins job info by passing job number
resp = tools[0].invoke({'job': "job01", "number": 1,
"action": "status"})
if not resp["inProgress"]:
print(resp["result"])
"""

job: str = Field(
description="name of the job"
)
action: str = Field(
description="action of the job, like, create, run, delete"
)
number: int = Field(
default=1,
description="job number"
)
config_xml: str = Field(
default='',
description="job xml content"
)
parameters: dict = Field(
default={},
description="job parameters"
)


class JenkinsJobRun(BaseTool): # type: ignore[override, override]
"""Tool that execute the job"""
name: str = "jenkins"
description: str = (
"""A tool that is used to create, trigger and delete Jenkins jobs with,
specified parameters."""
)
api_wrapper: JenkinsAPIWrapper = Field(default_factory=JenkinsAPIWrapper) # type: ignore[arg-type]
args_schema: Type[BaseModel] = JenkinsSchema


def _run(
self,
job: str,
action: str,
number: Optional[int] = 1,
config_xml: Optional[str] = "",
parameters: Optional[dict] = {},
run_manager: Optional[CallbackManagerForToolRun] = None,
) -> any:
"""Use the tool."""
if action == "create":
self.api_wrapper.create_job(
job=job,
config_xml=config_xml,
)
elif action == "run":
return self.api_wrapper.run_job(
job=job,
parameters=parameters,
)
elif action == "delete":
self.api_wrapper.delete_job(
job=job,
)
elif action == "status":
return self.api_wrapper.status_job(
job=job,
number=number
)
else:
raise ValueError("'action' not matched")
4 changes: 4 additions & 0 deletions libs/community/langchain_community/utilities/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@
from langchain_community.utilities.infobip import (
InfobipAPIWrapper,
)
from langchain_community.utilities.jenkins import (
JenkinsAPIWrapper
)
from langchain_community.utilities.jira import (
JiraAPIWrapper,
)
Expand Down Expand Up @@ -199,6 +202,7 @@
"GoogleTrendsAPIWrapper",
"GraphQLAPIWrapper",
"InfobipAPIWrapper",
"JenkinsAPIWrapper",
"JiraAPIWrapper",
"LambdaWrapper",
"MaxComputeAPIWrapper",
Expand Down
Loading

0 comments on commit 39cc487

Please sign in to comment.