diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 0c235c8..2b48946 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -14,7 +14,7 @@ jobs:
     - name: Install packages
       run: |
         sudo apt-get -y install pandoc
-      if: matrix.python-version == 3.8
+      if: matrix.python-version == 3.9
     - name: Set up Python ${{ matrix.python-version }}
       uses: actions/setup-python@v2
       with:
@@ -28,10 +28,10 @@ jobs:
       run: make test
     - name: Lint with flake8 ⚙️
       run: make lint
-      if: matrix.python-version == 3.8
+      if: matrix.python-version == 3.9
     - name: Check formatting with black ⚙️
-      run: black --check --target-version py36 birdy tests
-      if: matrix.python-version == 3.8
+      run: black --check --target-version py39 birdy tests
+      if: matrix.python-version == 3.9
     - name: Build docs 🏗️
       run: make docs
-      if: matrix.python-version == 3.8
+      if: matrix.python-version == 3.9
diff --git a/CHANGES.rst b/CHANGES.rst
index 487478e..76dd327 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -9,6 +9,7 @@ Changes:
 * Relax dependency check on GeoTiff rioxarray and rasterio converters due to some mysterious gdal error.
 * Remove tests with live 52North WPS server since it seems offline.
 * Remove Python 3.6 from test matrix and add 3.10.
+* Handle the removal of the `verbose` argument in `OWSLib.WebProcessingService` 0.29.0.
 
 0.8.1 (2021-12-01)
 ==================
diff --git a/birdy/client/base.py b/birdy/client/base.py
index 9a2684e..ccfa9d5 100644
--- a/birdy/client/base.py
+++ b/birdy/client/base.py
@@ -17,6 +17,8 @@ from owslib.wps import (
     ComplexData,
     WebProcessingService,
 )
+from warnings import warn
+import packaging.version
 
 from birdy.client import notebook, utils
 from birdy.client.outputs import WPSResult
@@ -46,13 +48,13 @@ class WPSClient(object):
         auth=None,
         verify=True,
         cert=None,
-        verbose=False,
         progress=False,
         version=WPS_DEFAULT_VERSION,
         caps_xml=None,
         desc_xml=None,
         language=None,
         lineage=False,
+        **kwds,
     ):
         """Initialize WPSClient.
 
@@ -77,8 +79,8 @@ class WPSClient(object):
           passed to :class:`owslib.wps.WebProcessingService`
         cert: str
           passed to :class:`owslib.wps.WebProcessingService`
-        verbose: str
-          passed to :class:`owslib.wps.WebProcessingService`
+        verbose: bool
+          Deprecated. passed to :class:`owslib.wps.WebProcessingService` for owslib < 0.29
         progress: bool
           If True, enable interactive user mode.
         version: str
@@ -117,17 +119,28 @@ class WPSClient(object):
             auth_headers = ["Authorization", "Proxy-Authorization", "Cookie"]
             headers.update({h: r.headers[h] for h in auth_headers if h in r.headers})
 
+        if "verbose" in kwds:
+            if packaging.version.parse(owslib.__version__) >= packaging.version.parse(
+                "0.29.0"
+            ):
+                kwds.pop("verbose")
+            warn(
+                "The 'verbose' keyword is deprecated and will be removed in a future version. Starting with owslib "
+                "0.29.0, debugging information is logged instead of printed.",
+                DeprecationWarning,
+            )
+
         self._wps = WebProcessingService(
             url,
             version=version,
             username=username,
             password=password,
-            verbose=verbose,
             headers=headers,
             verify=verify,
             cert=cert,
             skip_caps=True,
             language=language,
+            **kwds,
         )
 
         try:
@@ -309,7 +322,6 @@ class WPSClient(object):
             for value in values:
                 #  if input_param.dataType == "ComplexData": seems simpler
                 if isinstance(input_param.defaultValue, ComplexData):
-
                     # Guess the mimetype of the input value
                     mimetype, encoding = guess_type(value, supported_mimetypes)
 
diff --git a/birdy/client/notebook.py b/birdy/client/notebook.py
index 9ea1012..2b52719 100644
--- a/birdy/client/notebook.py
+++ b/birdy/client/notebook.py
@@ -114,7 +114,7 @@ class Form:
                 for (key, o) in outputs
             ]
         ):
-            for (key, output) in outputs:
+            for key, output in outputs:
                 if hasattr(output, "supportedValues"):
                     of[key] = widgets.RadioButtons(
                         options=[o.mimeType for o in output.supportedValues],
diff --git a/birdy/ipyleafletwfs/examples/ipyleafletwfs_guide.ipynb b/birdy/ipyleafletwfs/examples/ipyleafletwfs_guide.ipynb
index 4981ea9..046f5c6 100644
--- a/birdy/ipyleafletwfs/examples/ipyleafletwfs_guide.ipynb
+++ b/birdy/ipyleafletwfs/examples/ipyleafletwfs_guide.ipynb
@@ -19,8 +19,8 @@
     "from birdy import IpyleafletWFS\n",
     "from ipyleaflet import Map\n",
     "\n",
-    "url = 'http://boreas.ouranos.ca/geoserver/wfs'\n",
-    "version = '2.0.0'\n",
+    "url = \"http://boreas.ouranos.ca/geoserver/wfs\"\n",
+    "version = \"2.0.0\"\n",
     "\n",
     "wfs_connection = IpyleafletWFS(url, version)\n",
     "\n",
@@ -57,7 +57,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "wfs_connection.build_layer(layer_typename='public:HydroLAKES_poly', source_map=demo_map)"
+    "wfs_connection.build_layer(layer_typename=\"public:HydroLAKES_poly\", source_map=demo_map)"
    ]
   },
   {
@@ -95,8 +95,10 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "wfs_connection.create_feature_property_widget(widget_name='Wshd_area', feature_property='Wshd_area', widget_position='bottomleft')\n",
-    "demo_map\n"
+    "wfs_connection.create_feature_property_widget(\n",
+    "    widget_name=\"Wshd_area\", feature_property=\"Wshd_area\", widget_position=\"bottomleft\"\n",
+    ")\n",
+    "demo_map"
    ]
   },
   {
@@ -114,7 +116,9 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "wfs_connection.create_feature_property_widget(widget_name='main_widget', feature_property='Lake_area')"
+    "wfs_connection.create_feature_property_widget(\n",
+    "    widget_name=\"main_widget\", feature_property=\"Lake_area\"\n",
+    ")"
    ]
   },
   {
@@ -131,7 +135,7 @@
    "outputs": [],
    "source": [
     "gjson = wfs_connection.geojson\n",
-    "gjson['features'][0].keys()"
+    "gjson[\"features\"][0].keys()"
    ]
   },
   {
@@ -140,8 +144,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "\n",
-    "gjson['totalFeatures']\n"
+    "gjson[\"totalFeatures\"]"
    ]
   },
   {
@@ -157,7 +160,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "wfs_connection.create_feature_property_widget(widget_name='main_widget')\n",
+    "wfs_connection.create_feature_property_widget(widget_name=\"main_widget\")\n",
     "demo_map"
    ]
   },
diff --git a/birdy/ipyleafletwfs/examples/quickstart-template.ipynb b/birdy/ipyleafletwfs/examples/quickstart-template.ipynb
index 365bc2e..09cf30a 100644
--- a/birdy/ipyleafletwfs/examples/quickstart-template.ipynb
+++ b/birdy/ipyleafletwfs/examples/quickstart-template.ipynb
@@ -18,11 +18,11 @@
    "outputs": [],
    "source": [
     "from birdy import IpyleafletWFS\n",
-    "from ipyleaflet  import Map\n",
+    "from ipyleaflet import Map\n",
     "\n",
     "# Initialize the connection\n",
-    "url ='http://boreas.ouranos.ca/geoserver/wfs'\n",
-    "version ='2.0.0'\n",
+    "url = \"http://boreas.ouranos.ca/geoserver/wfs\"\n",
+    "version = \"2.0.0\"\n",
     "\n",
     "boreas_wfs = IpyleafletWFS(url, version)\n",
     "\n",
@@ -48,8 +48,7 @@
    "outputs": [],
    "source": [
     "# Build the WFS layer\n",
-    "boreas_wfs.build_layer(layer_typename='public:HydroLAKES_poly', source_map=m)\n",
-    "\n"
+    "boreas_wfs.build_layer(layer_typename=\"public:HydroLAKES_poly\", source_map=m)"
    ]
   },
   {
diff --git a/birdy/ipyleafletwfs/examples/wfs_constructor.ipynb b/birdy/ipyleafletwfs/examples/wfs_constructor.ipynb
index ab591ae..aa2ff3e 100644
--- a/birdy/ipyleafletwfs/examples/wfs_constructor.ipynb
+++ b/birdy/ipyleafletwfs/examples/wfs_constructor.ipynb
@@ -19,10 +19,10 @@
     "from ipyleaflet import Map\n",
     "\n",
     "# Create connection\n",
-    "url = 'http://boreas.ouranos.ca/geoserver/wfs'\n",
-    "version = '2.0.0'\n",
+    "url = \"http://boreas.ouranos.ca/geoserver/wfs\"\n",
+    "version = \"2.0.0\"\n",
     "\n",
-    "wfs = IpyleafletWFS(url, version)\n"
+    "wfs = IpyleafletWFS(url, version)"
    ]
   },
   {
@@ -33,7 +33,7 @@
    "source": [
     "# Create the map instance\n",
     "m = Map(center=(47.90, -69.90), zoom=11)\n",
-    "m\n"
+    "m"
    ]
   },
   {
@@ -55,11 +55,19 @@
     "# Create wfs layer\n",
     "# Move and zoom to the desired extent before running this cell\n",
     "# Do NOT zoom too far out, as large GeoJSON layers can be long to load and even cause crashed\n",
-    "basin_style = { 'color': '#d000ff', 'opacity': 1, 'dashArray': '10', 'fillOpacity': 0.0, 'weight': 3 }\n",
-    "lake_style = { 'color': '#00aeff', 'dashArray': '0', 'fillOpacity': 0.5, 'weight': 0.5 }\n",
+    "basin_style = {\n",
+    "    \"color\": \"#d000ff\",\n",
+    "    \"opacity\": 1,\n",
+    "    \"dashArray\": \"10\",\n",
+    "    \"fillOpacity\": 0.0,\n",
+    "    \"weight\": 3,\n",
+    "}\n",
+    "lake_style = {\"color\": \"#00aeff\", \"dashArray\": \"0\", \"fillOpacity\": 0.5, \"weight\": 0.5}\n",
     "\n",
-    "lakes = wfs.create_wfsgeojson_layer('public:HydroLAKES_poly', m, layer_style=lake_style)\n",
-    "basins = wfs.create_wfsgeojson_layer('public:wshed_bound_n2', m, layer_style=basin_style)"
+    "lakes = wfs.create_wfsgeojson_layer(\"public:HydroLAKES_poly\", m, layer_style=lake_style)\n",
+    "basins = wfs.create_wfsgeojson_layer(\n",
+    "    \"public:wshed_bound_n2\", m, layer_style=basin_style\n",
+    ")"
    ]
   },
   {

diff --git a/tests/test_client.py b/tests/test_client.py
index 78a8926..621c75e 100644
--- a/tests/test_client.py
+++ b/tests/test_client.py
@@ -409,3 +409,10 @@ class TestIsEmbedded:  # noqa: D101
     def test_url(self):  # noqa: D102
         assert not is_embedded_in_request(self.remote, self.url)
         assert not is_embedded_in_request(self.local, self.url)
+
+
+def test_verbose_deprecation():  # noqa: D103
+    with pytest.warns(DeprecationWarning):
+        WPSClient(
+            url=URL_EMU, caps_xml=EMU_CAPS_XML, desc_xml=EMU_DESC_XML, verbose=True
+        )

owslib removed verbose argument
## Description

The client has a `verbose` argument that it passes to `owslib.WebProcessingService`. In https://github.com/geopython/OWSLib/pull/864, it was removed without deprecation warning. 

I think we'll need to update birdy and pin owslib. 

## Additional Information

Links to other issues or sources.
https://github.com/geopython/OWSLib/pull/864


tests/test_client.py::test_emu_offline tests/test_client.py::test_wps_supported_languages tests/test_client.py::test_52north_offline tests/test_client.py::test_flyingpigeon_offline tests/test_client.py::test_wps_docs tests/test_client.py::test_wps_nb_form tests/test_client.py::test_verbose_deprecation
tests/test_client.py::test_sort_inputs tests/test_client.py::test_sort_inputs_conditions tests/test_client.py::TestIsEmbedded::test_string tests/test_client.py::TestIsEmbedded::test_file_like tests/test_client.py::TestIsEmbedded::test_local_fn tests/test_client.py::TestIsEmbedded::test_local_path tests/test_client.py::TestIsEmbedded::test_local_uri tests/test_client.py::TestIsEmbedded::test_url