Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[community] Add Jenkins tool support. #29430

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 221 additions & 0 deletions docs/docs/integrations/tools/jenkins.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
{
"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\"})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Chaining\n",
"Will comming soon..\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## API reference\n",
"\n",
"For detailed documentation [API reference](https://python.langchain.com/docs/integrations/tools/jenkins/)"
]
}
],
"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"]
100 changes: 100 additions & 0 deletions libs/community/langchain_community/tools/jenkins/tool.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""Tool for the Jenkins API"""

from typing import Any, 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):
"""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: int = 1,
config_xml: str = "",
parameters: dict = {},
run_manager: Optional[CallbackManagerForToolRun] = None,
) -> Any:
"""Use the tool."""
if action == "create":
return 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")
3 changes: 3 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,7 @@
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 +200,7 @@
"GoogleTrendsAPIWrapper",
"GraphQLAPIWrapper",
"InfobipAPIWrapper",
"JenkinsAPIWrapper",
"JiraAPIWrapper",
"LambdaWrapper",
"MaxComputeAPIWrapper",
Expand Down Expand Up @@ -263,6 +265,7 @@
"GoogleTrendsAPIWrapper": "langchain_community.utilities.google_trends",
"GraphQLAPIWrapper": "langchain_community.utilities.graphql",
"InfobipAPIWrapper": "langchain_community.utilities.infobip",
"JenkinsAPIWrapper": "langchain_community.utilities.jenkins",
"JiraAPIWrapper": "langchain_community.utilities.jira",
"LambdaWrapper": "langchain_community.utilities.awslambda",
"MaxComputeAPIWrapper": "langchain_community.utilities.max_compute",
Expand Down
Loading
Loading