├── .gitignore ├── img ├── figure1.png ├── figure2.png └── figure3.png ├── .env-dev ├── dotnet ├── AsFunctionTool │ ├── AsFunctionTool.csproj │ ├── ECommerceQuery.cs │ └── Program.cs └── Examples.sln ├── python ├── simple_agent_tools.py ├── elasticsearch_tools.py └── requirements.txt ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | /python/.venv 2 | /python/__pycache__ 3 | .env 4 | -------------------------------------------------------------------------------- /img/figure1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/agent-framework-examples/main/img/figure1.png -------------------------------------------------------------------------------- /img/figure2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/agent-framework-examples/main/img/figure2.png -------------------------------------------------------------------------------- /img/figure3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elastic/agent-framework-examples/main/img/figure3.png -------------------------------------------------------------------------------- /.env-dev: -------------------------------------------------------------------------------- 1 | ELASTICSEARCH_ENDPOINT="The endpoint of your Elasticsearch deployment here" 2 | ELASTICSEARCH_API_KEY="The API Key of your Elasticsearch deployment here" 3 | 4 | AZURE_OPENAI_ENDPOINT="The Azure OpenAI endpoint here" 5 | AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME="The Azure OpenAI deployment name here" 6 | AZURE_OPENAI_API_KEY="The API Key of your Azure OpenAI deployment here" 7 | 8 | -------------------------------------------------------------------------------- /dotnet/AsFunctionTool/AsFunctionTool.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Exe 5 | net9.0 6 | 7 | enable 8 | disable 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /dotnet/Examples.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.14.36518.9 d17.14 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AsFunctionTool", "AsFunctionTool\AsFunctionTool.csproj", "{E3B6EDBD-3456-7847-FEFB-B27F1965D5D1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {E3B6EDBD-3456-7847-FEFB-B27F1965D5D1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {E3B6EDBD-3456-7847-FEFB-B27F1965D5D1}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {E3B6EDBD-3456-7847-FEFB-B27F1965D5D1}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {E3B6EDBD-3456-7847-FEFB-B27F1965D5D1}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {5A389835-6319-4A06-8E71-97A809F8DC04} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /python/simple_agent_tools.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | import os 3 | from dotenv import load_dotenv 4 | 5 | from agent_framework.azure import AzureOpenAIResponsesClient 6 | from azure.identity import AzureCliCredential 7 | from elasticsearch_tools import ElasticsearchTools 8 | 9 | """ 10 | Azure AI Chat Client example with Elasticsearch integration 11 | 12 | Demonstrates direct AzureAIChatClient usage for chat interactions with Azure AI models. 13 | Shows function calling capabilities with Elasticsearch as a tool. 14 | """ 15 | 16 | async def main() -> None: 17 | tools = ElasticsearchTools() 18 | agent = AzureOpenAIResponsesClient(credential=AzureCliCredential()).create_agent( 19 | instructions="You are a helpful assistant for an ecommerce backend application.", 20 | tools=[tools.find_customer, tools.revenue_by_cities], 21 | ) 22 | 23 | # Example 1: Simple query to find a customer 24 | query = "Is Eddie Underwood our customer? If so, what is his email?" 25 | print(f"User: {query}") 26 | result = await agent.run(query) 27 | print(f"Result: {result}\n") 28 | 29 | # Example 2: More complex query with limit 30 | query = "List all customers with the last name 'Smith'. Limit to 5 results." 31 | print(f"User: {query}") 32 | result = await agent.run(query) 33 | print(f"Result: {result}\n") 34 | 35 | # Example 3: What are the first three city with more revenue? 36 | query = "What are the first three city with more revenue?" 37 | print(f"User: {query}") 38 | result = await agent.run(query) 39 | print(f"Result: {result}\n") 40 | 41 | if __name__ == "__main__": 42 | current_folder = os.path.dirname(os.path.abspath(__file__)) 43 | dotenv_path= current_folder + '/../.env' 44 | if not os.path.exists(dotenv_path): 45 | raise FileNotFoundError("Missing .env file. Please create one based on the .env-dev file.") 46 | load_dotenv(dotenv_path) 47 | asyncio.run(main()) -------------------------------------------------------------------------------- /dotnet/AsFunctionTool/ECommerceQuery.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Text.Json; 5 | using System.Threading.Tasks; 6 | using Elastic.Clients.Elasticsearch; 7 | 8 | internal sealed class ECommerceQuery 9 | { 10 | private readonly ElasticsearchClient _client; 11 | 12 | public ECommerceQuery(IElasticsearchClientSettings settings) 13 | { 14 | ArgumentNullException.ThrowIfNull(settings); 15 | 16 | this._client = new ElasticsearchClient(settings); 17 | } 18 | 19 | [Description("Get the customer information for a given name.")] 20 | public async Task> QueryCustomersAsync( 21 | [Description("The name of the customer to find.")] 22 | string name, 23 | [Description("The maximum number of results to return.")] 24 | int limit = 10) 25 | { 26 | IEnumerable response = await this._client.Esql 27 | .QueryAsObjectsAsync(x => x 28 | .Params( 29 | name, 30 | limit 31 | ) 32 | .Query(""" 33 | FROM kibana_sample_data_ecommerce 34 | | WHERE MATCH(customer_full_name, ?1, {"operator": "AND"}) 35 | | LIMIT ?2 36 | """ 37 | ) 38 | ) 39 | .ConfigureAwait(false); 40 | 41 | Console.WriteLine($"-- DEBUG - Tool: QueryCustomersAsync, ES|QL query parameters: name = {name}, limit = {limit}"); 42 | 43 | return response; 44 | } 45 | 46 | [Description("Get the total revenue grouped by city.")] 47 | public async Task> QueryRevenueAsync() 48 | { 49 | IEnumerable response = await this._client.Esql 50 | .QueryAsObjectsAsync(x => x 51 | .Query(""" 52 | FROM kibana_sample_data_ecommerce 53 | | STATS revenue = SUM(taxful_total_price) BY geoip.city_name 54 | | SORT revenue DESC 55 | | LIMIT 1000 56 | """) 57 | ) 58 | .ConfigureAwait(false); 59 | 60 | Console.WriteLine("-- DEBUG - Tool: QueryRevenueAsync"); 61 | 62 | return response; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /dotnet/AsFunctionTool/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ClientModel; 3 | using Azure.AI.OpenAI; 4 | using Elastic.Clients.Elasticsearch; 5 | using Elastic.Transport; 6 | using Microsoft.Agents.AI; 7 | using Microsoft.Extensions.AI; 8 | using OpenAI; 9 | 10 | var oaiEndpoint = 11 | Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT") 12 | ?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set."); 13 | var oaiDeploymentName = 14 | Environment.GetEnvironmentVariable("AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME") 15 | ?? throw new InvalidOperationException("AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME is not set."); 16 | var oaiKey = 17 | Environment.GetEnvironmentVariable("AZURE_OPENAI_KEY") 18 | ?? throw new InvalidOperationException("AZURE_OPENAI_KEY is not set."); 19 | 20 | var esEndpoint = 21 | Environment.GetEnvironmentVariable("ELASTICSEARCH_ENDPOINT") 22 | ?? throw new InvalidOperationException("ELASTICSEARCH_ENDPOINT is not set."); 23 | var esKey = 24 | Environment.GetEnvironmentVariable("ELASTICSEARCH_API_KEY") 25 | ?? throw new InvalidOperationException("ELASTICSEARCH_API_KEY is not set."); 26 | 27 | var eCommercePlugin = 28 | new ECommerceQuery( 29 | new ElasticsearchClientSettings(new SingleNodePool(new Uri(esEndpoint))) 30 | .Authentication(new ApiKey(esKey)) 31 | .EnableDebugMode() 32 | ); 33 | 34 | // Create the chat client and agent, and provide the function tool to the agent. 35 | var ecommerceAgent = new AzureOpenAIClient( 36 | new Uri(oaiEndpoint), 37 | new ApiKeyCredential(oaiKey)) 38 | .GetChatClient(oaiDeploymentName) 39 | .CreateAIAgent( 40 | instructions: "You are a helpful assistant for an ecommerce backend application.", 41 | name: "ECommerceAgent", 42 | description: "An agent that answers questions about orders in an ecommerce system.", 43 | tools: 44 | [ 45 | AIFunctionFactory.Create(eCommercePlugin.QueryCustomersAsync), 46 | AIFunctionFactory.Create(eCommercePlugin.QueryRevenueAsync) 47 | ] 48 | ); 49 | 50 | // Create the main agent, and provide the ecommerce agent as a function tool. 51 | var agent = new AzureOpenAIClient( 52 | new Uri(oaiEndpoint), 53 | new ApiKeyCredential(oaiKey)) 54 | .GetChatClient(oaiDeploymentName) 55 | .CreateAIAgent("You are a helpful assistant who responds in German.", tools: [ecommerceAgent.AsAIFunction()]); 56 | 57 | // Invoke the agent and output the text result. 58 | 59 | Console.WriteLine(await agent.RunAsync("Is Eddie Underwood our customer? If so, what is his email?")); 60 | Console.WriteLine(await agent.RunAsync("List all customers with the last name 'Smith'. Limit to 5 results.")); 61 | Console.WriteLine(await agent.RunAsync("What are the first three cities with the highest revenue?")); 62 | -------------------------------------------------------------------------------- /python/elasticsearch_tools.py: -------------------------------------------------------------------------------- 1 | import os 2 | from elasticsearch import Elasticsearch 3 | from typing import Annotated 4 | from pydantic import Field 5 | 6 | class ElasticsearchTools: 7 | def __init__(self, url: str = None, api_key: str = None): 8 | """ 9 | Initialize Elasticsearch client. 10 | 11 | Parameters 12 | ---------- 13 | url : str, optional 14 | Elasticsearch cluster URL. If not provided, falls back to 15 | environment variable ELASTICSEARCH_ENDPOINT. 16 | api_key : str, optional 17 | Elasticsearch API key. If not provided, falls back to 18 | environment variable ELASTICSEARCH_API_KEY. 19 | """ 20 | self.url = url or os.getenv("ELASTICSEARCH_ENDPOINT") 21 | self.api_key = api_key or os.getenv("ELASTICSEARCH_API_KEY") 22 | 23 | if not self.url or not self.api_key: 24 | raise ValueError("Missing Elasticsearch URL or API key.") 25 | 26 | self.client = Elasticsearch( 27 | [self.url], 28 | api_key=self.api_key 29 | ) 30 | 31 | # Test connection 32 | try: 33 | if not self.client.ping(): 34 | raise ConnectionError("Elasticsearch cluster is not reachable.") 35 | except Exception as e: 36 | raise ConnectionError(f"Failed to connect to Elasticsearch: {e}") 37 | 38 | def find_customer( 39 | self, 40 | name: Annotated[str, Field(description="The name of the customer to find.")], 41 | limit: Annotated[int, Field(description="The maximum number of results to return.", default=10)] 42 | ) -> str: 43 | """Get the customer information for a given name.""" 44 | query = f""" 45 | FROM kibana_sample_data_ecommerce 46 | | WHERE MATCH(customer_full_name,"{name}", {{"operator": "AND"}}) 47 | | LIMIT {limit} 48 | """ 49 | response = self.client.esql.query( 50 | query=query 51 | ) 52 | print(f"-- DEBUG - Tool: find_customer, ES|QL query: ", query) 53 | 54 | if response['documents_found'] == 0: 55 | return "No customer found." 56 | return f"Found {response['documents_found']} customer(s) with name {name}:\n {response['values']}" 57 | 58 | def revenue_by_cities( 59 | self 60 | ) -> str: 61 | """Get the total revenue grouped by city.""" 62 | query = f""" 63 | FROM kibana_sample_data_ecommerce 64 | | STATS revenue = SUM(taxful_total_price) BY geoip.city_name 65 | | SORT revenue DESC 66 | | LIMIT 1000 67 | """ 68 | response = self.client.esql.query( 69 | query=query 70 | ) 71 | print(f"-- DEBUG - Tool: revenue_by_cities, ES|QL query: ", query) 72 | 73 | if response['documents_found'] == 0: 74 | return "No revenue found grouped by city." 75 | return f"Total revenue grouped by cities:\n {response['values']}" -------------------------------------------------------------------------------- /python/requirements.txt: -------------------------------------------------------------------------------- 1 | a2a-sdk==0.3.7 2 | agent-framework==1.0.0b251001 3 | agent-framework-a2a==1.0.0b251001 4 | agent-framework-azure-ai==1.0.0b251001 5 | agent-framework-copilotstudio==1.0.0b251001 6 | agent-framework-core==1.0.0b251001 7 | agent-framework-devui==1.0.0b251001 8 | agent-framework-mem0==1.0.0b251001 9 | agent-framework-redis==1.0.0b251001 10 | aiofiles==24.1.0 11 | aiohappyeyeballs==2.6.1 12 | aiohttp==3.12.15 13 | aiosignal==1.4.0 14 | annotated-types==0.7.0 15 | anyio==4.11.0 16 | asgiref==3.9.2 17 | attrs==25.3.0 18 | azure-ai-agents==1.2.0b5 19 | azure-ai-projects==1.1.0b4 20 | azure-core==1.35.1 21 | azure-core-tracing-opentelemetry==1.0.0b12 22 | azure-identity==1.25.0 23 | azure-monitor-opentelemetry==1.8.1 24 | azure-monitor-opentelemetry-exporter==1.0.0b42 25 | azure-storage-blob==12.26.0 26 | backoff==2.2.1 27 | cachetools==6.2.0 28 | certifi==2025.8.3 29 | cffi==2.0.0 30 | charset-normalizer==3.4.3 31 | click==8.3.0 32 | cryptography==46.0.2 33 | distro==1.9.0 34 | elastic-transport==9.1.0 35 | elasticsearch==9.1.1 36 | fastapi==0.118.0 37 | fixedint==0.1.6 38 | frozenlist==1.7.0 39 | google-api-core==2.25.1 40 | google-auth==2.41.1 41 | googleapis-common-protos==1.70.0 42 | greenlet==3.2.4 43 | grpcio==1.75.1 44 | h11==0.16.0 45 | h2==4.3.0 46 | hpack==4.1.0 47 | httpcore==1.0.9 48 | httptools==0.6.4 49 | httpx==0.28.1 50 | httpx-sse==0.4.1 51 | hyperframe==6.1.0 52 | idna==3.10 53 | importlib_metadata==8.7.0 54 | isodate==0.7.2 55 | jiter==0.11.0 56 | jsonpath-ng==1.7.0 57 | jsonschema==4.25.1 58 | jsonschema-specifications==2025.9.1 59 | mcp==1.15.0 60 | mem0ai==0.1.118 61 | microsoft-agents-activity==0.3.2 62 | microsoft-agents-copilotstudio-client==0.3.2 63 | microsoft-agents-hosting-core==0.3.2 64 | ml_dtypes==0.5.3 65 | msal==1.34.0 66 | msal-extensions==1.3.1 67 | msrest==0.7.1 68 | multidict==6.6.4 69 | numpy==2.3.3 70 | oauthlib==3.3.1 71 | openai==1.109.1 72 | opentelemetry-api==1.37.0 73 | opentelemetry-exporter-otlp-proto-common==1.37.0 74 | opentelemetry-exporter-otlp-proto-grpc==1.37.0 75 | opentelemetry-instrumentation==0.58b0 76 | opentelemetry-instrumentation-asgi==0.58b0 77 | opentelemetry-instrumentation-dbapi==0.58b0 78 | opentelemetry-instrumentation-django==0.58b0 79 | opentelemetry-instrumentation-fastapi==0.58b0 80 | opentelemetry-instrumentation-flask==0.58b0 81 | opentelemetry-instrumentation-psycopg2==0.58b0 82 | opentelemetry-instrumentation-requests==0.58b0 83 | opentelemetry-instrumentation-urllib==0.58b0 84 | opentelemetry-instrumentation-urllib3==0.58b0 85 | opentelemetry-instrumentation-wsgi==0.58b0 86 | opentelemetry-proto==1.37.0 87 | opentelemetry-resource-detector-azure==0.1.5 88 | opentelemetry-sdk==1.37.0 89 | opentelemetry-semantic-conventions==0.58b0 90 | opentelemetry-semantic-conventions-ai==0.4.13 91 | opentelemetry-util-http==0.58b0 92 | packaging==25.0 93 | ply==3.11 94 | portalocker==3.2.0 95 | posthog==6.7.6 96 | propcache==0.3.2 97 | proto-plus==1.26.1 98 | protobuf==5.29.5 99 | psutil==7.1.0 100 | pyasn1==0.6.1 101 | pyasn1_modules==0.4.2 102 | pycparser==2.23 103 | pydantic==2.11.9 104 | pydantic-settings==2.11.0 105 | pydantic_core==2.33.2 106 | PyJWT==2.10.1 107 | python-dateutil==2.9.0.post0 108 | python-dotenv==1.1.1 109 | python-multipart==0.0.20 110 | python-ulid==3.1.0 111 | pytz==2025.2 112 | PyYAML==6.0.3 113 | qdrant-client==1.15.1 114 | redis==6.4.0 115 | redisvl==0.9.1 116 | referencing==0.36.2 117 | requests==2.32.5 118 | requests-oauthlib==2.0.0 119 | rpds-py==0.27.1 120 | rsa==4.9.1 121 | six==1.17.0 122 | sniffio==1.3.1 123 | SQLAlchemy==2.0.43 124 | sse-starlette==3.0.2 125 | starlette==0.48.0 126 | tenacity==9.1.2 127 | tqdm==4.67.1 128 | typing==3.7.4.3 129 | typing-inspection==0.4.2 130 | typing_extensions==4.15.0 131 | urllib3==2.5.0 132 | uvicorn==0.37.0 133 | uvloop==0.21.0 134 | watchfiles==1.1.0 135 | websockets==15.0.1 136 | wrapt==1.17.3 137 | yarl==1.20.1 138 | zipp==3.23.0 139 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Elasticsearch code examples for Microsoft Agent Framework 2 | 3 | This repository contains some examples in Python and .NET for using the 4 | [Microsoft Agent Framework](https://github.com/microsoft/agent-framework) with Elasticsearch. 5 | 6 | This repository is part of the article [Building agentic applications with Elasticsearch and Microsoft’s Agent Framework](https://www.elastic.co/search-labs/blog/agentic-applications-elasticsearch-microsoft-agent-framework) 7 | published in the Elastic search labs website by [Elastic](https://www.elastic.co/). 8 | 9 | ## Microsoft Agent Framework 10 | 11 | Microsof Agetn Framework is a comprehensive multi-language framework for building, orchestrating, and deploying AI agents with support for both .NET and Python implementations. This framework provides everything from simple chat agents to complex multi-agent workflows with graph-based orchestration. 12 | 13 | For more information you can read this [Microsoft announcement](https://azure.microsoft.com/en-us/blog/introducing-microsoft-agent-framework/). 14 | 15 | ## Run Elasticsearch 16 | 17 | To execute the examples reported in this repository you need to have an 18 | instance of [Elasticsearch](https://www.elastic.co/elasticsearch) running. You can register for a free trial on 19 | [Elastic Cloud](https://www.elastic.co/cloud/cloud-trial-overview) or install a local instance of Elasticsearch on your computer. 20 | 21 | To install locally, you need to execute this command in the terminal: 22 | 23 | ```bash 24 | curl -fsSL https://elastic.co/start-local | sh 25 | ``` 26 | 27 | This will install Elasticsearch and [Kibana](https://www.elastic.co/kibana) on macOS, Linux and Windows using WSDL. 28 | 29 | ## Use the sample data in Kibana 30 | 31 | The examples reported in this repository use a sample data provided by Kibana. 32 | You need to import this sample data using the following procedure: 33 | 34 | - After the login in Kibana, open the navigation menu on the left and select 35 | **Integrations** page in the navigation bar on the left (Figure 1). 36 | 37 | ![Figure 1](/img/figure1.png) 38 | 39 | - In the Integrations page, search for "sample" and click on **Sample Data** (Figure 2) 40 | 41 | ![Figure 2](/img/figure2.png) 42 | 43 | - Finally, in the Sample data page, click on **Other sample data sets** and click 44 | on **Add data** for the Sample eCommerce orders use case (Figure 3). 45 | 46 | ![Figure 3](/img/figure3.png) 47 | 48 | The ecommerce data will be stored in an index called `kibana_sample_data_ecommerce` containing about 4,675 orders. 49 | 50 | ## Configure Azure AI 51 | 52 | In the examples, We used Azure OpenAI. You need to configure a `.env` 53 | file containing the following environmental variables: 54 | 55 | ``` 56 | ELASTICSEARCH_ENDPOINT="The endpoint of your Elasticsearch deployment here" 57 | ELASTICSEARCH_API_KEY="The API Key of your Elasticsearch deployment here" 58 | 59 | AZURE_OPENAI_ENDPOINT="The Azure OpenAI endpoint here" 60 | AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME="The Azure OpenAI deployment name here" 61 | AZURE_OPENAI_API_KEY="The API Key of your Azure OpenAI deployment here" 62 | ``` 63 | 64 | You can generate the `.env` file copying if from `.env-dev` file. 65 | 66 | If you installed Elasticsearch using [start-local](https://github.com/elastic/start-local), 67 | you can read the endpoint and api key from the `.env` file of the folder installation. 68 | 69 | For Azure OpenAI you can read the value settings in the Azure portal. 70 | 71 | ## Python examples 72 | 73 | To install the Python examples, you can create and activate a virtual 74 | environment ([venv](https://docs.python.org/3/library/venv.html)) in the `python` folder. 75 | 76 | Use the following commands from the root folder of the repository: 77 | 78 | ```bash 79 | cd python 80 | python -m venv .venv 81 | source .venv/bin/activate 82 | ``` 83 | 84 | After, you can install all the required packages as follows: 85 | 86 | ```bash 87 | pip install -r requirements.txt 88 | ``` 89 | 90 | Now, you can execute the examples. For instance, you can run the `simple_agent_tools.py` 91 | with the following command: 92 | 93 | ```bash 94 | python simple_agent_tools.py 95 | ``` 96 | 97 | This example build an agent that can interact with Elasticsearch using some tools. 98 | The tools are implemented in the [python/elasticsearch_tools.py](/python/elasticsearch_tools.py) file. 99 | 100 | ## .NET examples 101 | 102 | To run the .NET examples, simply navigate to the directory of a specific example and start the program: 103 | 104 | ```bash 105 | cd dotnet/{example name} 106 | dotnet run 107 | ``` 108 | 109 | Please ensure that you set the necessary environment variables according to your setup. 110 | 111 | ## License 112 | 113 | This software is licensed under the [Apache License 2.0](./LICENSE) 114 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | --------------------------------------------------------------------------------