- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
We have a Splunk html view. We are trying to call a python script. Currently the code looks like this (retyped since our Splunk server doesn't have web access, I tried to avoid typos):
function callScript(){
$.ajax({
type: "POST",
url: "bin/my_script.py",
data: {'flag': defaultTokenModel.get("form.flag"))
},
success: function() {
alert("success returned");
}
});
}
This doesn't work. The success message is returned, but the actual python script isn't called.
From what I can tell, it looks like there may be a method called ajax in simplifyxml/mvc.js which is conflicting with the JQuery method, though I'm not certain that is the case.
What is the proper way to make a script call like this?
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

This won't work as you think. Access to local folders within an app is not allowed for security and technical reasons.
When you make that POST call, you are actually trying to get a Web UI relative script! https:///en-US/app/myapp/bin/my_script.py
for example. This just doesn't work.
So, you cannot directly call a python script from the web ui, it is not accessible. There is a way to do this. It is a method not fully documented, but involves creating a custom endpoint for Splunk, and then calling that endpoint.
Let me start with a quick tutorial. I'll gloss over a few things, make assumptions, drink some beer. Comment with questions. 😄
web.conf
[endpoint:my_script]
So, that is the only line you need in web.conf
. This tells Splunk that you are creating a new web endpoint. The my_script
definition needs to have the same name as the python file located in $APP_HOME/appserver/controllers
. (Where $APP_HOME
is the folder of the app you are creating this in - I'd suggest a new app, not search).
$APP_HOME/appserver/controllers/my_script.py
import logging
import os
import sys
# from splunk import AuthorizationFailed as AuthorizationFailed
import splunk.appserver.mrsparkle.controllers as controllers
import splunk.appserver.mrsparkle.lib.util as util
from splunk.appserver.mrsparkle.lib.util import make_splunkhome_path
from splunk.appserver.mrsparkle.lib.decorators import expose_page
_APPNAME = 'MyAppName'
def setup_logger(level):
"""
Setup a logger for the REST handler.
"""
logger = logging.getLogger('splunk.appserver.%s.controllers.my_script' % _APPNAME)
logger.propagate = False # Prevent the log messages from being duplicated in the python.log file
logger.setLevel(level)
file_handler = logging.handlers.RotatingFileHandler(
make_splunkhome_path(['var', 'log', 'splunk', 'my_script_controller.log']), maxBytes=25000000, backupCount=5)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
logger = setup_logger(logging.DEBUG)
class my_script(controllers.BaseController):
# /custom/MyAppName/my_script/my_endpoint
@expose_page(must_login=True, methods=['GET'])
def my_endpoint(self, **kwargs):
# DO YOUR THINGS WITH THE KWARGS PASSED
Whoa. WTF is that!? Python! YAY! So, now you have an endpoint enabled. Now you can call it from your HTML view.
function callScript(){
$.get("/custom/MyAppName/my_script/my_endpoint",
{'flag': defaultTokenModel.get("form.flag")) } )
.done(function(data){
});
}
Pay attention to these strings throughout this tutorial: my_script
, my_endpoint
, MyAppName
. This all need to be changed to your specification, they are merely examples. Again, this should at least point you in the right direction on doing this call. If you have questions, please follow up here, or find me on IRC (#splunk on efnet - I'm alacer) or via the Splunk Slack channel for usergroups, just ping me @alacercogitatus.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

I am new to app development. I am not able to find out a way to add default token model to my js. It will be really helpful if you can guide me.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

This won't work as you think. Access to local folders within an app is not allowed for security and technical reasons.
When you make that POST call, you are actually trying to get a Web UI relative script! https:///en-US/app/myapp/bin/my_script.py
for example. This just doesn't work.
So, you cannot directly call a python script from the web ui, it is not accessible. There is a way to do this. It is a method not fully documented, but involves creating a custom endpoint for Splunk, and then calling that endpoint.
Let me start with a quick tutorial. I'll gloss over a few things, make assumptions, drink some beer. Comment with questions. 😄
web.conf
[endpoint:my_script]
So, that is the only line you need in web.conf
. This tells Splunk that you are creating a new web endpoint. The my_script
definition needs to have the same name as the python file located in $APP_HOME/appserver/controllers
. (Where $APP_HOME
is the folder of the app you are creating this in - I'd suggest a new app, not search).
$APP_HOME/appserver/controllers/my_script.py
import logging
import os
import sys
# from splunk import AuthorizationFailed as AuthorizationFailed
import splunk.appserver.mrsparkle.controllers as controllers
import splunk.appserver.mrsparkle.lib.util as util
from splunk.appserver.mrsparkle.lib.util import make_splunkhome_path
from splunk.appserver.mrsparkle.lib.decorators import expose_page
_APPNAME = 'MyAppName'
def setup_logger(level):
"""
Setup a logger for the REST handler.
"""
logger = logging.getLogger('splunk.appserver.%s.controllers.my_script' % _APPNAME)
logger.propagate = False # Prevent the log messages from being duplicated in the python.log file
logger.setLevel(level)
file_handler = logging.handlers.RotatingFileHandler(
make_splunkhome_path(['var', 'log', 'splunk', 'my_script_controller.log']), maxBytes=25000000, backupCount=5)
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
file_handler.setFormatter(formatter)
logger.addHandler(file_handler)
return logger
logger = setup_logger(logging.DEBUG)
class my_script(controllers.BaseController):
# /custom/MyAppName/my_script/my_endpoint
@expose_page(must_login=True, methods=['GET'])
def my_endpoint(self, **kwargs):
# DO YOUR THINGS WITH THE KWARGS PASSED
Whoa. WTF is that!? Python! YAY! So, now you have an endpoint enabled. Now you can call it from your HTML view.
function callScript(){
$.get("/custom/MyAppName/my_script/my_endpoint",
{'flag': defaultTokenModel.get("form.flag")) } )
.done(function(data){
});
}
Pay attention to these strings throughout this tutorial: my_script
, my_endpoint
, MyAppName
. This all need to be changed to your specification, they are merely examples. Again, this should at least point you in the right direction on doing this call. If you have questions, please follow up here, or find me on IRC (#splunk on efnet - I'm alacer) or via the Splunk Slack channel for usergroups, just ping me @alacercogitatus.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Hi,
I created one endpoint following your instruction.
It is working fine for GET requests but giving 405(Method not allowed)/500 (internal server error) for POST request.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@alacercogitatus: Thanks for posting this. I was actually looking for this.
I tried the way you mentioned above, but seems to be something went wrong, I am seeing 404 error in my browser console and my HTML view shows nothing.
http://localhost:8000/en-US/custom/MyAppName/my_script/my_endpoint?_=1462458361563 Failed to load resource: the server responded with a status of 404 (Not Found).
Can you help me to resolve this?
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Did you restart ? Once you make the changes to create the endpoint, you have to restart.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I did restarted, but no luck.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Check that the Python is compiling, ($SPLUNK_HOME/bin/splunk cmd python ./my_script.py
) and then check the internal splunk logs for errors and warnings.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Seems to be python compiling is issue, I am very new to python, have to see how this compiling stuff works.
Also, do I need to compile each time when I modified python code? will that won't work, If I hit HTML view directly in browser?
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

You don't need to "compile" each time, it's just a simple way to check that you have proper syntax. Fix the syntax, and it should work after a restart.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My Python code compiles well. Nothing is there in that .py file, simple print statement.
Still I am seeing 404 error with python call - http://localhost:8000/en-US/custom/MyApp/my_script/my_endpoint.
Any other suggestions?
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It works now. Thanks
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

Oh, can you let me know how you fixed it? I am having the same problem despite my python script compiling.
Thanks!
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Added "cherrypy.response.headers['Content-Type'] = 'text/plain'" statement in "my_endpoint" definition.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

That didn't do anything. I don't think its necessary. Still getting the same error. Also, there's nothing in the generated log file.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Just getting back to this. I did this but it didn't quite work for me, I'm getting a 500 error when I try to post (my original example was a post not a get, I went ahead and coverted over to POSTS). I think the problem is that I have the wrong URL to post to...
Currently my URL to the HTML page is something like
hostname/splunk/en-us/app/MyAppName/html_file
your example says that the url starts at custom, but I wasn't expecting custom, and I don't know what that URL is relative to. If I want to connect directly to my rest url to verify something is happening what URL should I be using?
Sorry to ask such a basic question, this is the sort of thing I shouldn't need help with. but I feel blind here, not sure where any documentation is to check on my own; I've been looking lol.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

So to construct the URL, you need 3 things. 1) Name of your App 2) Name of the Endpoint 3) name of the function.
Then it goes such like: /custom/APPNAME/ENDPOINT/FUNCTION
The /custom
denotes that this is a custom endpoint and is required for this to work. So if your "script" (located in $APP_HOME/appserver/controllers/
) is called html_file.py
, and the function in that file is called post_this
, then your URL in the HTML dashboard will be /custom/MyAppName/html_file/post_this
. Done.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
I tried the above but in my python, i have the error below:
ImportError: No module named cherrypy
isn't this cherrypy packaged with splunk as default? or do i need to install it?
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content

System installed python will not have that module, and I think that is what you tried to do. Use Splunk's python instead: $SPLUNK_HOME/bin/splunk cmd python myscript.py
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi alacercogitatus!
I really appreciate your quick response. Thank you.
I will try that! but which folder should myscript.py be in to do that?
I'm wondering cause i am trying ajax, aswell, to call python script but I don't know what kind of 'URL' i should write for that.
- Mark as New
- Bookmark Message
- Subscribe to Message
- Mute Message
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is an interesting example, doubly so for me since I've done something very similar but in a different way. Please take a look at this post:
Return binary data (such as images) via REST API
There, I used [expose:...] stanzas in web.conf and my additions to restmap.conf. This made my endpoint visible under /services via admin port, which is something I feel is not quite appropriate and very cumbersome. Where is your approach documented?
