@@ -559,8 +559,8 @@ def parse(self, query, **kwargs):
559559 :return: A semantic map of the parsed search query.
560560 """
561561 if self .splunk_version >= (9 ,):
562- return self .get ("search/v2/parser" , q = query , ** kwargs )
563- return self .post ("search/parser" , q = query , ** kwargs )
562+ return self .post ("search/v2/parser" , q = query , ** kwargs )
563+ return self .get ("search/parser" , q = query , ** kwargs )
564564
565565 def restart (self , timeout = None ):
566566 """Restarts this Splunk instance.
@@ -793,6 +793,13 @@ def get(self, path_segment="", owner=None, app=None, sharing=None, **query):
793793 app = app , sharing = sharing )
794794 # ^-- This was "%s%s" % (self.path, path_segment).
795795 # That doesn't work, because self.path may be UrlEncoded.
796+
797+ # Search API v2 fallback to v1:
798+ # - In v2, /results_preview, /events and /results do not support search params.
799+ # - Fallback from v2 to v1 if Splunk Version is < 9.
800+ if (PATH_JOBS_V2 in path and 'search' in query and path .endswith (tuple (["results_preview" , "events" , "results" ]))) or self .service .splunk_version < (9 ,):
801+ path = path .replace (PATH_JOBS_V2 , PATH_JOBS )
802+
796803 return self .service .get (path ,
797804 owner = owner , app = app , sharing = sharing ,
798805 ** query )
@@ -845,13 +852,20 @@ def post(self, path_segment="", owner=None, app=None, sharing=None, **query):
845852 apps.get('nonexistant/path') # raises HTTPError
846853 s.logout()
847854 apps.get() # raises AuthenticationError
848- """
855+ """
849856 if path_segment .startswith ('/' ):
850857 path = path_segment
851858 else :
852859 if not self .path .endswith ('/' ) and path_segment != "" :
853860 self .path = self .path + '/'
854861 path = self .service ._abspath (self .path + path_segment , owner = owner , app = app , sharing = sharing )
862+
863+ # Search API v2 fallback to v1:
864+ # - In v2, /results_preview, /events and /results do not support search params.
865+ # - Fallback from v2 to v1 if Splunk Version is < 9.
866+ if (PATH_JOBS_V2 in path and 'search' in query and path .endswith (tuple (["results_preview" , "events" , "results" ]))) or self .service .splunk_version < (9 ,):
867+ path = path .replace (PATH_JOBS_V2 , PATH_JOBS )
868+
855869 return self .service .post (path , owner = owner , app = app , sharing = sharing , ** query )
856870
857871
@@ -2661,14 +2675,17 @@ def oneshot(self, path, **kwargs):
26612675
26622676
26632677class Job (Entity ):
2664-
26652678 """This class represents a search job."""
2666- def __init__ (self , service , sid , defaultPath , ** kwargs ):
2667-
2668- # Don't provide a path, allow it to be dynamically generated
2669- Entity .__init__ (self , service , '' , skip_refresh = True , ** kwargs )
2679+ def __init__ (self , service , sid , ** kwargs ):
2680+ # Default to v2 in Splunk Version 9+
2681+ path = "{path}{sid}"
2682+ path = path .format (path = PATH_JOBS_V2 , sid = sid )
2683+ # Fallback to v1 if Splunk Version < 9
2684+ if service .splunk_version < (9 ,):
2685+ path = path .format (path = PATH_JOBS , sid = sid )
2686+
2687+ Entity .__init__ (self , service , path , skip_refresh = True , ** kwargs )
26702688 self .sid = sid
2671- self .defaultPath = defaultPath + sid + '/'
26722689
26732690 # The Job entry record is returned at the root of the response
26742691 def _load_atom_entry (self , response ):
@@ -2680,7 +2697,7 @@ def cancel(self):
26802697 :return: The :class:`Job`.
26812698 """
26822699 try :
2683- self .post (self . defaultPath + "control" , action = "cancel" )
2700+ self .post ("control" , action = "cancel" )
26842701 except HTTPError as he :
26852702 if he .status == 404 :
26862703 # The job has already been cancelled, so
@@ -2695,7 +2712,7 @@ def disable_preview(self):
26952712
26962713 :return: The :class:`Job`.
26972714 """
2698- self .post (self . defaultPath + "control" , action = "disablepreview" )
2715+ self .post ("control" , action = "disablepreview" )
26992716 return self
27002717
27012718 def enable_preview (self ):
@@ -2705,7 +2722,7 @@ def enable_preview(self):
27052722
27062723 :return: The :class:`Job`.
27072724 """
2708- self .post (self . defaultPath + "control" , action = "enablepreview" )
2725+ self .post ("control" , action = "enablepreview" )
27092726 return self
27102727
27112728 def events (self , ** kwargs ):
@@ -2720,19 +2737,14 @@ def events(self, **kwargs):
27202737 :return: The ``InputStream`` IO handle to this job's events.
27212738 """
27222739 kwargs ['segmentation' ] = kwargs .get ('segmentation' , 'none' )
2723- path = "{path}{sid}/events"
2724-
2725- # Splunk version doesn't support v2 (pre-9.0) or the 'search' arg is included (which is v1 specific)
2726- if self .splunk_version < (9 ,) or 'search' in kwargs :
2727- return self .get (path .format (PATH_JOBS , self .sid ), ** kwargs ).body
2728- return self .get (path .format (PATH_JOBS_V2 , self .sid ), ** kwargs ).body
2740+ return self .get ("events" , ** kwargs ).body
27292741
27302742 def finalize (self ):
27312743 """Stops the job and provides intermediate results for retrieval.
27322744
27332745 :return: The :class:`Job`.
27342746 """
2735- self .post (self . defaultPath + "control" , action = "finalize" )
2747+ self .post ("control" , action = "finalize" )
27362748 return self
27372749
27382750 def is_done (self ):
@@ -2753,7 +2765,7 @@ def is_ready(self):
27532765 :rtype: ``boolean``
27542766
27552767 """
2756- response = self .get (self . defaultPath )
2768+ response = self .get ()
27572769 if response .status == 204 :
27582770 return False
27592771 self ._state = self .read (response )
@@ -2774,7 +2786,7 @@ def pause(self):
27742786
27752787 :return: The :class:`Job`.
27762788 """
2777- self .post (self . defaultPath + "control" , action = "pause" )
2789+ self .post ("control" , action = "pause" )
27782790 return self
27792791
27802792 def results (self , ** query_params ):
@@ -2813,12 +2825,7 @@ def results(self, **query_params):
28132825 :return: The ``InputStream`` IO handle to this job's results.
28142826 """
28152827 query_params ['segmentation' ] = query_params .get ('segmentation' , 'none' )
2816- path = "{path}{sid}/results"
2817-
2818- # Splunk version doesn't support v2 (pre-9.0) or the 'search' arg is included (which is v1 specific)
2819- if self .splunk_version < (9 ,) or 'search' in query_params :
2820- return self .get (path .format (PATH_JOBS , self .sid ), ** query_params ).body
2821- return self .get (path .format (PATH_JOBS_V2 , self .sid ), ** query_params ).body
2828+ return self .get ("results" , ** query_params ).body
28222829
28232830 def preview (self , ** query_params ):
28242831 """Returns a streaming handle to this job's preview search results.
@@ -2859,12 +2866,7 @@ def preview(self, **query_params):
28592866 :return: The ``InputStream`` IO handle to this job's preview results.
28602867 """
28612868 query_params ['segmentation' ] = query_params .get ('segmentation' , 'none' )
2862- path = "{path}{sid}/results_preview"
2863-
2864- # Splunk version doesn't support v2 (pre-9.0) or the 'search' arg is included (which is v1 specific)
2865- if self .splunk_version < (9 ,) or 'search' in query_params :
2866- return self .get (path .format (PATH_JOBS , self .sid ), ** query_params ).body
2867- return self .get (path .format (PATH_JOBS_V2 , self .sid ), ** query_params ).body
2869+ return self .get ("results_preview" , ** query_params ).body
28682870
28692871 def searchlog (self , ** kwargs ):
28702872 """Returns a streaming handle to this job's search log.
@@ -2877,7 +2879,7 @@ def searchlog(self, **kwargs):
28772879
28782880 :return: The ``InputStream`` IO handle to this job's search log.
28792881 """
2880- return self .get (self . defaultPath + "search.log" , ** kwargs ).body
2882+ return self .get ("search.log" , ** kwargs ).body
28812883
28822884 def set_priority (self , value ):
28832885 """Sets this job's search priority in the range of 0-10.
@@ -2890,7 +2892,7 @@ def set_priority(self, value):
28902892
28912893 :return: The :class:`Job`.
28922894 """
2893- self .post (self . defaultPath + 'control' , action = "setpriority" , priority = value )
2895+ self .post ('control' , action = "setpriority" , priority = value )
28942896 return self
28952897
28962898 def summary (self , ** kwargs ):
@@ -2904,7 +2906,7 @@ def summary(self, **kwargs):
29042906
29052907 :return: The ``InputStream`` IO handle to this job's summary.
29062908 """
2907- return self .get (self . defaultPath + "summary" , ** kwargs ).body
2909+ return self .get ("summary" , ** kwargs ).body
29082910
29092911 def timeline (self , ** kwargs ):
29102912 """Returns a streaming handle to this job's timeline results.
@@ -2917,15 +2919,15 @@ def timeline(self, **kwargs):
29172919
29182920 :return: The ``InputStream`` IO handle to this job's timeline.
29192921 """
2920- return self .get (self . defaultPath + "timeline" , ** kwargs ).body
2922+ return self .get ("timeline" , ** kwargs ).body
29212923
29222924 def touch (self ):
29232925 """Extends the expiration time of the search to the current time (now) plus
29242926 the time-to-live (ttl) value.
29252927
29262928 :return: The :class:`Job`.
29272929 """
2928- self .post (self . defaultPath + "control" , action = "touch" )
2930+ self .post ("control" , action = "touch" )
29292931 return self
29302932
29312933 def set_ttl (self , value ):
@@ -2937,15 +2939,15 @@ def set_ttl(self, value):
29372939
29382940 :return: The :class:`Job`.
29392941 """
2940- self .post (self . defaultPath + "control" , action = "setttl" , ttl = value )
2942+ self .post ("control" , action = "setttl" , ttl = value )
29412943 return self
29422944
29432945 def unpause (self ):
29442946 """Resumes the current search, if paused.
29452947
29462948 :return: The :class:`Job`.
29472949 """
2948- self .post (self . defaultPath + "control" , action = "unpause" )
2950+ self .post ("control" , action = "unpause" )
29492951 return self
29502952
29512953
@@ -2954,7 +2956,7 @@ class Jobs(Collection):
29542956 collection using :meth:`Service.jobs`."""
29552957 def __init__ (self , service ):
29562958 # Splunk 9 introduces the v2 endpoint
2957- if self .splunk_version >= (9 ,):
2959+ if service .splunk_version >= (9 ,):
29582960 path = PATH_JOBS_V2
29592961 else :
29602962 path = PATH_JOBS
@@ -2995,7 +2997,7 @@ def create(self, query, **kwargs):
29952997 raise TypeError ("Cannot specify exec_mode=oneshot; use the oneshot method instead." )
29962998 response = self .post (search = query , ** kwargs )
29972999 sid = _load_sid (response )
2998- return Job (self .service , sid , self . path )
3000+ return Job (self .service , sid )
29993001
30003002 def export (self , query , ** params ):
30013003 """Runs a search and immediately starts streaming preview events. This method returns a streaming handle to
@@ -3796,4 +3798,4 @@ def batch_save(self, *documents):
37963798
37973799 data = json .dumps (documents )
37983800
3799- return json .loads (self ._post ('batch_save' , headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ().decode ('utf-8' ))
3801+ return json .loads (self ._post ('batch_save' , headers = KVStoreCollectionData .JSON_HEADER , body = data ).body .read ().decode ('utf-8' ))
0 commit comments