obsidian-python-runner: A plugin to run any python scripts in Obsidian editor
Developed an Obsidian plugin using windsurf that can run any Python script in the editor and output the results to the editor. The calling method is simple:
@py function_in_python_scripts()
Additionally, you can pass the current document’s information to the Python script by passing ‘doc’ as a parameter. This feature is demonstrated in the example.py program:
def docinfos(doc):
from datetime import datetime
"""Display detailed information about the current document"""
info = {
"Available fields": list(doc.keys()),
"Document title": doc['title'],
"File path": doc['path'],
"Creation time": datetime.fromtimestamp(doc['created']/1000),
"Modification time": datetime.fromtimestamp(doc['modified']/1000),
"Content length": len(doc['content']),
"Cursor position": doc['cursor'],
}
return info
In the Obsidian editor, input:
@py docinfos(doc)
to get the basic information of the current document.
{'Available fields':
['title', 'path', 'created', 'modified', 'content', 'frontmatter', 'cursor', 'selection'],
'Document title': 'A plugin to run any python scripts in Obsidian editor',
'File path': 'A plugin to run any python scripts in Obsidian editor.md',
'Creation time': datetime.datetime(2025, 1, 30, 18, 20, 4, 924000), 'Modification time': datetime.datetime(2025, 2, 9, 19, 31, 2, 909000),
'Content length': 1046,
'Cursor position': {'line': 36, 'ch': 0}}
Code for communicating with Deepseek through their API:
def deepseek_r1(query):
from openai import OpenAI
"""Use the Reasoner model through the DeepSeek API, which will output its reasoning process and final answer."""
api_key="your api key"
base_url="https://api.deepseek.com"
try:
ds = OpenAI(api_key=api_key, base_url=base_url)
response = ds.chat.completions.create(
model='deepseek-reasoner',
messages=[
{"role": "system", "content": "You are an office assistant"},
{"role": "user", "content": query},
],
max_tokens=8192,
temperature=0.8,
stream=False
)
message = response.choices[0].message.content
reasoning_content = response.choices[0].message.reasoning_content
r = f"{reasoning_content}\n\n{message}"
return(r)
except Exception as e:
return str(e)
def deepseek_chat(query):
from openai import OpenAI
"""Use the Chat model through the DeepSeek API, which will output the final answer."""
api_key="your api key"
base_url="https://api.deepseek.com"
try:
ds = OpenAI(api_key=api_key, base_url=base_url)
response = ds.chat.completions.create(
model='deepseek-chat',
messages=[
{"role": "system", "content": "You are an office assistant"},
{"role": "user", "content": query},
],
max_tokens=8192,
temperature=0.8,
stream=False
)
message = response.choices[0].message.content
return(message)
except Exception as e:
return str(e)
You can type @py deepseek_r1(query) or @py deepseek_chat(query) in the editor to send request to Deepseek.
The deepseek_r1 and deepseek_chat functions use DeepSeek’s R1 and V3 models respectively, and can be chosen according to needs. Although R1 is better, it costs 4 times more than V3. Choose what’s right, not what’s expensive.
The original intention of developing this plugin was to directly communicate with AI in Obsidian’s editor. Although there is an existing plugin called Smart composer with similar functionality, it didn’t quite meet my requirements. Many people are advocating for AI’s programming capabilities, believing that the programmer profession will disappear. As I had zero experience with Obsidian plugin development, I took this opportunity to test how good AI’s programming capabilities really are. The result was that, despite having no knowledge of TypeScript or plugin development standards, I was able to develop it using windsurf in less than an hour, with functionality that fully met expectations. It must be said that artificial intelligence can indeed be quite useful at times.
Link to my Obsidian plugin obsidian-python-runner