The Web Outside of Browsers Project allows users to access Internet data in a generic way without using a Web Browser.
Woob offers a common interface for accessing a variety of different Internet data sources. So rather than using a specific API to access to weather and then another to access a job boards, the Woob API/tools can be used for both of these data sources.
Woob can be used as a:
- Python library,
- A command line tool, or by
- Bash scripting
In this blog I wanted to document my Linux notes on:
- basic command line tool usage
- Bash/Python examples for getting weather data
- Bash/Python examples for playing Internet streaming music
Note: WOOB is in development so features may change. Also there is a large list of application modules, but at present most are European based.
Getting Started
To install woob:
$ pip install woob
Once woob is installed a list of features can be shown by entering woob:
$ woob
usage: woob [--version] <command> [<args>]
Use one of this commands:
bands display bands and suggestions
bank manage bank accounts
bill get/download documents and bills
books manage rented books
bugtracker manage bug tracking issues
calendar see upcoming events
cinema search movies and persons around cinema
cli call a method on backends
config manage backends or register new accounts
contentedit manage websites content
dating interact with dating websites
debug debug backends
gallery browse and download web image galleries
gauge display sensors and gauges values
geolocip geolocalize IP addresses
housing search for housing
job search for a job
lyrics search and display song lyrics
money import bank accounts into Microsoft Money
msg send and receive message threads
parcel manage your parcels
paste post and get pastes from pastebins
pricecompare compare products
radio search, show or listen to radio stations
recipes search and consult recipes
repos manage a woob repository
rpg manage RPG data
shop obtain details and status of e-commerce orders
smtp daemon to send and check messages
subtitles search and download subtitles
torrent search and download torrents
translate translate text from one language to another
travel search for train stations and departures
video search and play videos
weather display weather and forecasts
For more information about a command, use:
$ man woob-<command>
or
$ woob <command> --help
Each features has a backend (database) associated with it. For example to define the weather.com backend for the weather command:
$ woob weather
Warning: there is currently no configured backend for weather
Do you want to configure backends? (Y/n): y
Available modules:
1) [ ] ilmatieteenlaitos Get forecasts from the Ilmatieteenlaitos.fi website
2) [ ] lameteoagricole lameteoagricole website
3) [ ] meteofrance Get forecasts from the MeteoFrance website
4) [ ] weather Get forecasts from weather.com
a) --all-- install all backends
q) --stop--
Select a backend to create (q to stop): 4
Backend "weather" successfully added.
If a backend needs to be removed, for example meteofrance, use the backend remove command:
$ wood weather backend remove meteofrance
To check which backends are defined, use the backend list command:
$ woob weather backend list
Enabled: weather
$ woob radio backend list
Enabled: freeteknomusic, somafm
Using the Weather Command
Woob offers a number of weather modules. A good generic option is weather.com.
To get started at the command line, enter: woob weather
$ woob weather
Welcome to weather v3.0
Copyright(C) 2010-2022 Romain Bignon
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Type "help" to display available commands.
Loaded backends: weather
weather> help
Weather Commands:
cities PATTERN
current CITY_ID
debug
forecasts CITY_ID
Woob Commands:
formatter [list | FORMATTER [COMMAND] | option OPTION_NAME [on | off]]
select [FIELD_NAME]... | "$direct" | "$full"
ls [-d] [-U] [PATH]
cd [PATH]
condition [EXPRESSION | off]
count [NUMBER | off]
backends [ACTION] [BACKEND_NAME]...
quit
logging [LEVEL]
Type "help <command>" for more info about a command.
The first step is to search for a city with the cities option. Once a city is found the id (1-20) is used to show the current weather and the future forecast.
The example below searches for Toronto. The first item (Toronto, Ontario, Canada) is selected (current 1) to show the present Toronto weather. Toronto’s future weather can be checked with the forecast command (forecast 1).

Bash Scripting for Weather
The command line utility can be used with Bash script, (For more info on the interface).
A scripting example to show the current and forecast weather for Toronto (the first item in the list):
$ # use the -n 1 option to get the first item
$ woob weather cities 'Toronto' -n 1
d8ccf908e3c4c748e232720575df7cdbca6e0f1b412bca8595d8a28d0c28e8bc@weather — Toronto, Ontario, Canada
$ # get the id (first string) and save to a variable
$ city_id=$(woob weather cities 'Toronto' -n 1 | awk '{print $1}')
$ # pass the city id to get the weather current
$ woob weather current $city_id
2022-12-08: -1 °C - 1030.2hPa (Rising) - humidity 73% - feels like -4 °C/24 °F - Fair
An example is to get the current weather for a place and show it as a Linux system tray notification:
$ # Create a notification note with current weather information
$ my_city="Sauble Beach"
$ city_id=$(woob weather cities "$my_city" -n 1 | awk '{print $1}')
$ notify-send -t 1000000 "$my_city" "$(woob weather current $city_id )

To show the long term forecast information in a Zenity dialog:
$ # Create an Info Dialog with weather forecast information
$ my_city="Sauble Beach"
$ city_id=$(woob weather cities "$my_city" -n 1 | awk '{print $1}')
$ wf=$(woob weather forecast $city_id)
$ zenity --width=650 --info --text="$wf" --title="$my_city"

Python Woob Weather Example
A Python example to select the first city in a list and then show the forecast would be:
#!/usr/bin/python3
#
# wweather.py - Search for weather forecast for a place
#
from woob.core import Woob
from woob.capabilities.weather import CapWeather
w=Woob()
w.load_backends(CapWeather)
# Find the id for a location
for city in w.iter_city_search("Sauble Beach"):
# stop at first hit
print(city.id, city.name)
break
# Get the Forecast for that location
for w0 in w.iter_forecast(city.id):
print("Date:", w0.date)
print("Forecast:", w0.text)
print("High:", w0.high)
print("Low", w0.low, "\n")
For more information on the Weather calls.
Using the Radio Command
There are a number of radio modules to choose from. The first step is to add at least one module:
$ woob radio
Warning: there is currently no configured backend for radio
Do you want to configure backends? (Y/n): y
Available modules:
1) [ ] audioaddict Internet radios powered by audioaddict.com services
2) [ ] bandcamp Bandcamp music website
3) [ ] freeteknomusic freeteknomusic website
4) [ ] ina INA French TV video archives
5) [ ] nectarine Nectarine Demoscene Radio
6) [ ] nova Nova French radio
7) [ ] ouifm OÜI FM French radio
8) [ ] radiofrance Radios of Radio France: Inter, Info, Bleu, Culture, Musique, FIP, Le Mouv'
9) [ ] somafm SomaFM web radio
10) [ ] virginradio VirginRadio french radio
a) --all-- install all backends
q) --stop--
Select a backend to create (q to stop): 9
Backend "somafm" successfully added.
After one of more radio modules are added, you can search for radio stations that play a genre:
$ woob radio
Welcome to radio v3.0
Type "help" to display available commands.
Loaded backends: freeteknomusic, somafm
radio> search radio trance
id: thetrip@somafm
title: The Trip
description: Progressive house / trance. Tip top tunes.
current: B With U (Salinas' Dub Mix) - Tommyboy And Soultan Feat. Zara
streams: ['130Kbps/aac' ('http://somafm.com/thetrip130.pls'), 'fast/mp3' ('http://somafm.com/thetrip.pls'), '64Kbps/aacp' ('http://somafm.com/thetrip64.pls'), '32Kbps/aacp' ('http://somafm.com/thetrip32.pls')]
radio:/search> play 1
For this radio station search of “trance” only 1 station was found, so play 1 is used to listen to that station. (Note: if 3 were returned then you could listen to the third station by: play 3).
Bash Scripting for Internet Radio
There are some woob options that will make scripting a little easier. Some genres like “rock” or “ambient” will return too many hits, so the -n option can be set to limit the number of returned items. The -s option will return only selected fields.
$ # Show the id and description
$ # for the first 2 ambient station
$ woob radio search radio "ambient" -s id,description -n 2
id: deepspaceone@somafm
description: Deep ambient electronic, experimental and space music. For inner and outer space exploration.
id: groovesalad@somafm
description: A nicely chilled plate of ambient/downtempo beats and grooves.
An example script (wlisten.sh) takes a music genre entered on the command line and then finds and plays the first related station.
#!/bin/bash
#
# wlisten.sh - find a Woob Radio station and play it
#
echo -e "\nWoob Internet Radio Player\n"
echo -n "Enter a type of Music to listen to: "
read mtype
echo "Now playing : $mtype music ..."
woob radio play $(woob radio search radio "$mtype" -n 1 -s id | awk '{print $2}' )
To run this script (wlisten.sh) to play a reggae station:
$ bash wlisten.sh
Woob Internet Radio Player
Enter a type of Music to listen to: reggae
Now playing : reggae music ...
This example only uses the first returned station. By using a couple of Zenity list dialongs a Bash script can be created to present a list of preset genres, then the user can select a specific station.
#!/bin/bash
#
# wradio.sh - find a Woob Radio station and play it
#
mtype=$(zenity --title="Play Internet Radio" \
--list --height=500 --width=300 --column="Music Type" \
80s Ambient Dance House Jazz Pop Rock Reggae Top Trance)
# if a music type is selected then get stations
echo "Music Type: $mtype"
if [[ -n "$mtype" ]] ; then
stn=$(woob radio search radio $mtype -f radio_list | zenity --list \
--title="Select Radio Station" \
--column=station --column=description --width=900 --height=300)
# Get the station ID, its the 1st part of the station string
stn_id="${stn%%—*}"
# If the station string is not empty, play the station
if [[ -n "$stn_id" ]] ; then
echo "Station Id: $stn_id"
woob radio play $stn_id
fi
fi

Python Woob Radio Example
To get a selection of radio stations for a genre:
from woob.core import Woob
from woob.capabilities.radio import CapRadio
w = Woob()
w.load_backends(CapRadio)
genre="rock"
for stns in w.iter_radios_search(genre):
print(stns.id, stns.title, stns.description, "\n")
See the Woob tech api docs for more details on the radio API.
A Python Tkinter GUI example to select a genre and then play a radio station:
#!/usr/bin/python3
#
# wradio.py - Tkinter GUI for Woob Radio
#
from tkinter import *
from tkinter import ttk
import subprocess
from woob.core import Woob
from woob.capabilities.radio import CapRadio
w = Woob()
w.load_backends(CapRadio)
# Fill the tree with genre stations
def show_stations():
genre = cbo.get()
tree.delete(*tree.get_children())
# Insert Rows into tree based on found radio stations
for stns in w.iter_radios_search(genre):
tree.insert('','end',text=stns.id,values=(stns.id, stns.title, stns.description))
# Play selected station
def tree_getitem(a):
curItem = tree.focus()
stn_info=tree.item(curItem) # station is dictionary variable
thestn=stn_info['text'] # get the station id
p=subprocess.Popen(["killall", "woob"])
p=subprocess.Popen(["killall", "mpv"])
if thestn != "":
labelText.set("Playing Station: " + thestn)
p=subprocess.Popen(["woob", "radio", "play", thestn])
def stop_music():
labelText.set("")
p=subprocess.Popen(["killall", "woob"])
p=subprocess.Popen(["killall", "mpv"])
# Create an instance of tkinter frame
root = Tk()
genre="Rock"
root.title('Play Internet Radio Stations')
root.geometry('900x300')
# Create a listbox of station genres
label1 = ttk.Label(text = "Enter a genre: ").grid(row=0,column=0)
cbo = ttk.Combobox(root,height = 1)
genres= {"80s","Ambient", "Dance", "House","Jazz","Pop","Rock", "Reggae","Trance"}
cbo['value'] = [m for m in genres]
cbo.grid(row=0, column=1)
# Create a button to update station tree
bt_update = ttk.Button(root,text="Select Genre", command=show_stations)
bt_update.grid(row=0, column=2)
# Create a tree list with 3 columns
tree = ttk.Treeview(root, column=("Id","Station", "Desciption"), show='headings')
tree.column("#1", width=100)
tree.heading("#1", text="ID")
tree.column("#2", width=200)
tree.heading("#2", text="Station")
tree.column("#3", width=600)
tree.heading("#3", text="Description")
tree.grid(row=1, column=0, columnspan=3)
tree.bind('<ButtonRelease-1>', tree_getitem)
# Create a label to show station being played
labelText = StringVar()
label2 = ttk.Label(textvariable=labelText).grid(row=2,column=0)
# Add a button to start and stop music
bt_stop = ttk.Button(root,text="Stop Music", command=stop_music)
bt_stop.grid(row=2,column=1)
root.mainloop()

Summary
The Woob project has a lot of potential, however because it is still in the development stage it can be a little challenging to use.
Due to the lack of examples, I found that I was able to get up and running faster with Bash scripts rather than Python. To build a Bash script I would first test what I wanted to do in the online tool, then I would mimic this in Bash.