class_docstr: OpenAPIServiceToFunctions is responsible for converting an OpenAPI service specification into a format suitable
  for OpenAI function calling, based on the provided OpenAPI specification. Given an OpenAPI specification,
  OpenAPIServiceToFunctions processes it, and extracts function definitions that can be invoked via OpenAI's
  function calling mechanism. The format of the extracted functions is compatible with OpenAI's function calling
  JSON format.
  
  Minimal requirements for OpenAPI specification:
  - OpenAPI version 3.0.0 or higher
  - Each function must have a unique operationId
  - Each function must have a description
  - Each function must have a requestBody or parameters or both
  - Each function must have a schema for the requestBody and/or parameters
  
  
  See https://github.com/OAI/OpenAPI-Specification for more details on OpenAPI specification.
  See https://platform.openai.com/docs/guides/function-calling for more details on OpenAI function calling.
class_docstr_tok: ["OpenAPIServiceToFunctions","is","responsible","for","converting","an","OpenAPI","service","specification","into","a","format","suitable","for","OpenAI","function","calling",",","based","on","the","provided","OpenAPI","specification",".","Given","an","OpenAPI","specification",",","OpenAPIServiceToFunctions","processes","it",",","and","extracts","function","definitions","that","can","be","invoked","via","OpenAI's","function","calling","mechanism",".","The","format","of","the","extracted","functions","is","compatible","with","OpenAI","'s","function","calling","JSON","format",".","Minimal","requirements","for","OpenAPI","specification",":","-","OpenAPI","version","3.0.0","or","higher","-","Each","function","must","have","a","unique","operationId","-","Each","function","must","have","a","description","-","Each","function","must","have","a","requestBody","or","parameters","or","both","-","Each","function","must","have","a","schema","for","the","requestBody","and\/or","parameters","See","https",":","\/\/github.com\/OAI\/OpenAPI-Specification","for","more","details","on","OpenAPI","specification",".","See","https",":","\/\/platform.openai.com\/docs\/guides\/function-calling","for","more","details","on","OpenAI","function","calling","."]
docstr: Extracts functions from the OpenAPI specification of the service and converts them into a format
  suitable for OpenAI function calling.
  
  :param service_openapi_spec: The OpenAPI specification from which functions are to be extracted.
  :type service_openapi_spec: Dict[str, Any]
  :return: A list of dictionaries, each representing a function. Each dictionary includes the function's
           name, description, and a schema of its parameters.
  :rtype: List[Dict[str, Any]]
docstr_tok: ["Extracts","functions","from","the","OpenAPI","specification","of","the","service","and","converts","them","into","a","format","suitable","for","OpenAI","function","calling",".",":","param","service_openapi_spec",":","The","OpenAPI","specification","from","which","functions","are","to","be","extracted",".",":","type","service_openapi_spec",":","Dict","[","str",",","Any","]",":","return",":","A","list","of","dictionaries",",","each","representing","a","function",".","Each","dictionary","includes","the","function's","name",",","description",",","and","a","schema","of","its","parameters",".",":","rtype",":","List","[","Dict","[","str",",","Any","]","]"]
code: def _openapi_to_functions(
      self, service_openapi_spec: Dict[str, Any]
  ) -> List[Dict[str, Any]]:
      """
      Extracts functions from the OpenAPI specification of the service and converts them into a format
      suitable for OpenAI function calling.
  
      :param service_openapi_spec: The OpenAPI specification from which functions are to be extracted.
      :type service_openapi_spec: Dict[str, Any]
      :return: A list of dictionaries, each representing a function. Each dictionary includes the function's
               name, description, and a schema of its parameters.
      :rtype: List[Dict[str, Any]]
      """
  
      # Doesn't enforce rigid spec validation because that would require a lot of dependencies
      # We check the version and require minimal fields to be present, so we can extract functions
      spec_version = service_openapi_spec.get("openapi")
      if not spec_version:
          raise ValueError(
              f"Invalid OpenAPI spec provided. Could not extract version from {service_openapi_spec}"
          )
      service_openapi_spec_version = int(spec_version.split(".")[0])
  
      # Compare the versions
      if (
          service_openapi_spec_version
          < OpenAPIServiceToFunctions.MIN_REQUIRED_OPENAPI_SPEC_VERSION
      ):
          raise ValueError(
              f"Invalid OpenAPI spec version {service_openapi_spec_version}. Must be "
              f"at least {OpenAPIServiceToFunctions.MIN_REQUIRED_OPENAPI_SPEC_VERSION}."
          )
  
      functions: List[Dict[str, Any]] = []
      for path_methods in service_openapi_spec["paths"].values():
          for method_specification in path_methods.values():
              resolved_spec = jsonref.replace_refs(method_specification)
              if isinstance(resolved_spec, dict):
                  function_name = resolved_spec.get("operationId")
                  desc = resolved_spec.get(
                      "description"
                  ) or resolved_spec.get("summary", "")
  
                  schema: Dict[str, Any] = {
                      "type": "object",
                      "properties": {},
                  }
  
                  req_body = (
                      resolved_spec.get("requestBody", {})
                      .get("content", {})
                      .get("application/json", {})
                      .get("schema")
                  )
                  if req_body:
                      schema["properties"]["requestBody"] = req_body
  
                  params = resolved_spec.get("parameters", [])
                  if params:
                      param_properties = {
                          param["name"]: param["schema"]
                          for param in params
                          if "schema" in param
                      }
                      schema["properties"]["parameters"] = {
                          "type": "object",
                          "properties": param_properties,
                      }
  
                  # these three fields are minimal requirement for OpenAI function calling
                  if function_name and desc and schema:
                      functions.append(
                          {
                              "name": function_name,
                              "description": desc,
                              "parameters": schema,
                          }
                      )
                  else:
                      logger.warning(
                          "Invalid OpenAPI spec format provided. Could not extract function from %s",
                          resolved_spec,
                      )
  
              else:
                  logger.warning(
                      "Invalid OpenAPI spec format provided. Could not extract function from %s",
                      resolved_spec,
                  )
  
      return functions
  
file_path: haystack/haystack/components/converters/openapi_functions.py
imports: import json
  import logging
  import os
  from pathlib import Path
  from typing import List, Dict, Any, Union, Optional
  import requests
  import yaml
  from requests import RequestException
  from haystack import component, Document
  from haystack.dataclasses.byte_stream import ByteStream
  from haystack.lazy_imports import LazyImport
label_desc: Use image node_id 3 for calling the OpenAPIServiceToFunctions obj's underlying member method code with example usage: obj._openapi_to_functions(service_openapi_spec) and returns: functions