π Plugins & Extensions#
Need to fetch data from a specialized local server? Or maybe run a custom script immediately after every download? You donβt need to fork the repo!
There are two ways to extend fetchez: Local Plugins (for quick, personal scripts) and Full Extensions (for distributable Python packages).
Local Plugins (Quick & Easy)#
Local plugins are standalone Python scripts that you drop into your local fetchez configuration folders. fetchez automatically scans these folders at runtime and registers any valid classes it finds.
Data Modules (~/.fetchez/plugins/)#
Data Modules tell fetchez how to talk to a specific API or data source.
To build one, create a Python script containing a class that inherits from fetchez.core.FetchModule.
Example:
Create ~/.fetchez/plugins/my_server.py:
from fetchez.modules import FetchModule
class MyCustomServer(FetchModule):
name = "my_server"
meta_desc = "Fetches data from my local company server."
def __init__(self, **kwargs):
super().__init__(name="my_server", **kwargs)
def run(self):
# Your custom logic to query an API and yield URLs goes here.
self.results.append({
"url": "http://myserver.local/data.zip",
"dst_fn": "data.zip"
})
You can now run this instantly from the CLI: fetchez my_server
Processing Hooks (~/.fetchez/hooks/)#
Hooks intercept data before, during, or after the fetch process.
To build one, create a class that inherits from fetchez.hooks.FetchHook.
Example:
Create ~/.fetchez/hooks/zulip_notify.py:
import logging
from fetchez.hooks import FetchHook
logger = logging.getLogger(__name__)
class ZulipNotifier(FetchHook):
name = "zulip_notify"
meta_stage = "post"
meta_category = "comms"
def __init__(self, chan="fetchez", **kwargs):
super().__init__(**kwargs)
self.chan = chan
def run(self, entries):
import zulip
client = zulip.Client()
mods = set()
for mod, entry in entries:
mods.add(mod)
params = {
"type": "stream",
"to": self.chan,
"topic": "Auto-Fetchez",
"content": f"Downloaded {len(entries)} files from {len(mods)} modules."
}
result = client.send_message(params)
logger.info(f"Zulip notification result: {result.get('result')}!")
return entries
You can now use this in your presets, recipes and cli switches: fetchez copernicus --hook zulip_notify