diff --git a/docker/Dockerfile b/docker/Dockerfile
index 19f7441ebc2f006d00eb016daa4263601ad61411..94cc5e283719ab1fd9d4a419c5f6adc7943a6a2c 100644
--- a/docker/Dockerfile
+++ b/docker/Dockerfile
@@ -9,4 +9,5 @@ RUN sudo echo "resolvconf resolvconf/linkify-resolvconf boolean false" | sudo de
 RUN sudo apt-get install -y keyboard-configuration
 RUN sudo apt-get install -y qtcreator libxrender1 gdb
 RUN sudo apt-get install -y fonts-ubuntu
+RUN sudo apt install python3-pygccxml
 CMD ["/usr/bin/qtcreator"]
diff --git a/include/bladeRF/source.h b/include/bladeRF/source.h
index 42474d383e942cc35cbe23a43c5bd922de1e15c3..fff492921f63666a8a4314b39581eb536b99f31b 100644
--- a/include/bladeRF/source.h
+++ b/include/bladeRF/source.h
@@ -34,7 +34,7 @@ namespace gr {
        * class. bladeRF::source::make is the public interface for
        * creating new instances.
        */
-      static sptr make(const std::string & args);
+      static sptr make(const std::string & args = "");
 
       /*!
        * Get the number of channels the underlying radio hardware offers.
diff --git a/python/bindings/docstrings/sink_pydoc_template.h b/python/bindings/docstrings/sink_pydoc_template.h
index 635b3d346ff9a8e9db83d1eb7f966626160b6090..ddad61836a4dc9a8d84b5f2581a61ca0c34e1983 100644
--- a/python/bindings/docstrings/sink_pydoc_template.h
+++ b/python/bindings/docstrings/sink_pydoc_template.h
@@ -19,6 +19,105 @@
  static const char *__doc_gr_bladeRF_sink = R"doc()doc";
 
 
+ static const char *__doc_gr_bladeRF_sink_sink_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_sink_1 = R"doc()doc";
+
+
  static const char *__doc_gr_bladeRF_sink_make = R"doc()doc";
 
+
+ static const char *__doc_gr_bladeRF_sink_get_num_channels = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_sample_rates = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_freq_range = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_center_freq = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_center_freq = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_gain_names = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_gain_range_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_gain_range_1 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_if_gain = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_bb_gain = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_antennas = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_antenna = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_antenna = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_dc_offset = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_iq_balance = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_bandwidth_range = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_set_clock_source = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_clock_source = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_sink_get_clock_sources = R"doc()doc";
+
   
diff --git a/python/bindings/docstrings/source_pydoc_template.h b/python/bindings/docstrings/source_pydoc_template.h
index 59144c3c05cf3da4b8334f40b7de7ecbb4df4c4f..f5d97d90d1d71fa17026ab3381649372d87a5adc 100644
--- a/python/bindings/docstrings/source_pydoc_template.h
+++ b/python/bindings/docstrings/source_pydoc_template.h
@@ -19,6 +19,102 @@
  static const char *__doc_gr_bladeRF_source = R"doc()doc";
 
 
+ static const char *__doc_gr_bladeRF_source_source_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_source_1 = R"doc()doc";
+
+
  static const char *__doc_gr_bladeRF_source_make = R"doc()doc";
 
+
+ static const char *__doc_gr_bladeRF_source_get_num_channels = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_sample_rates = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_sample_rate = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_freq_range = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_center_freq = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_center_freq = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_freq_corr = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_gain_names = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_gain_range_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_gain_range_1 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_gain_mode = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_gain_0 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_gain_1 = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_if_gain = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_bb_gain = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_antennas = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_antenna = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_antenna = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_dc_offset_mode = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_dc_offset = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_iq_balance_mode = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_iq_balance = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_set_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_bandwidth = R"doc()doc";
+
+
+ static const char *__doc_gr_bladeRF_source_get_bandwidth_range = R"doc()doc";
+
   
diff --git a/python/bindings/sink_python.cc b/python/bindings/sink_python.cc
index 64c8b535ca5716420b42186c68a3e1ce18110b2c..f144b0fd09a8098a04d0af082b41c0b9ce44df2c 100644
--- a/python/bindings/sink_python.cc
+++ b/python/bindings/sink_python.cc
@@ -30,20 +30,249 @@ namespace py = pybind11;
 void bind_sink(py::module& m)
 {
 
-    using sink    = gr::bladeRF::sink;
+    using sink    = ::gr::bladeRF::sink;
 
 
-    py::class_<sink,
+    py::class_<sink, gr::hier_block2,
         std::shared_ptr<sink>>(m, "sink", D(sink))
 
         .def(py::init(&sink::make),
-           py::arg("args") =  "",
+           py::arg("args") = "",
            D(sink,make)
         )
         
 
 
 
+
+        
+        .def("get_num_channels",&sink::get_num_channels,       
+            D(sink,get_num_channels)
+        )
+
+
+        
+        .def("get_sample_rates",&sink::get_sample_rates,       
+            D(sink,get_sample_rates)
+        )
+
+
+        
+        .def("set_sample_rate",&sink::set_sample_rate,       
+            py::arg("rate"),
+            D(sink,set_sample_rate)
+        )
+
+
+        
+        .def("get_sample_rate",&sink::get_sample_rate,       
+            D(sink,get_sample_rate)
+        )
+
+
+        
+        .def("get_freq_range",&sink::get_freq_range,       
+            py::arg("chan") = 0,
+            D(sink,get_freq_range)
+        )
+
+
+        
+        .def("set_center_freq",&sink::set_center_freq,       
+            py::arg("freq"),
+            py::arg("chan") = 0,
+            D(sink,set_center_freq)
+        )
+
+
+        
+        .def("get_center_freq",&sink::get_center_freq,       
+            py::arg("chan") = 0,
+            D(sink,get_center_freq)
+        )
+
+
+        
+        .def("set_freq_corr",&sink::set_freq_corr,       
+            py::arg("ppm"),
+            py::arg("chan") = 0,
+            D(sink,set_freq_corr)
+        )
+
+
+        
+        .def("get_freq_corr",&sink::get_freq_corr,       
+            py::arg("chan") = 0,
+            D(sink,get_freq_corr)
+        )
+
+
+        
+        .def("get_gain_names",&sink::get_gain_names,       
+            py::arg("chan") = 0,
+            D(sink,get_gain_names)
+        )
+
+
+        
+        .def("get_gain_range",(osmosdr::gain_range_t (sink::*)(size_t))&sink::get_gain_range,       
+            py::arg("chan") = 0,
+            D(sink,get_gain_range,0)
+        )
+
+
+        
+        .def("get_gain_range",(osmosdr::gain_range_t (sink::*)(std::string const &, size_t))&sink::get_gain_range,       
+            py::arg("name"),
+            py::arg("chan") = 0,
+            D(sink,get_gain_range,1)
+        )
+
+
+        
+        .def("set_gain_mode",&sink::set_gain_mode,       
+            py::arg("automatic"),
+            py::arg("chan") = 0,
+            D(sink,set_gain_mode)
+        )
+
+
+        
+        .def("get_gain_mode",&sink::get_gain_mode,       
+            py::arg("chan") = 0,
+            D(sink,get_gain_mode)
+        )
+
+
+        
+        .def("set_gain",(double (sink::*)(double, size_t))&sink::set_gain,       
+            py::arg("gain"),
+            py::arg("chan") = 0,
+            D(sink,set_gain,0)
+        )
+
+
+        
+        .def("set_gain",(double (sink::*)(double, std::string const &, size_t))&sink::set_gain,       
+            py::arg("gain"),
+            py::arg("name"),
+            py::arg("chan") = 0,
+            D(sink,set_gain,1)
+        )
+
+
+        
+        .def("get_gain",(double (sink::*)(size_t))&sink::get_gain,       
+            py::arg("chan") = 0,
+            D(sink,get_gain,0)
+        )
+
+
+        
+        .def("get_gain",(double (sink::*)(std::string const &, size_t))&sink::get_gain,       
+            py::arg("name"),
+            py::arg("chan") = 0,
+            D(sink,get_gain,1)
+        )
+
+
+        
+        .def("set_if_gain",&sink::set_if_gain,       
+            py::arg("gain"),
+            py::arg("chan") = 0,
+            D(sink,set_if_gain)
+        )
+
+
+        
+        .def("set_bb_gain",&sink::set_bb_gain,       
+            py::arg("gain"),
+            py::arg("chan") = 0,
+            D(sink,set_bb_gain)
+        )
+
+
+        
+        .def("get_antennas",&sink::get_antennas,       
+            py::arg("chan") = 0,
+            D(sink,get_antennas)
+        )
+
+
+        
+        .def("set_antenna",&sink::set_antenna,       
+            py::arg("antenna"),
+            py::arg("chan") = 0,
+            D(sink,set_antenna)
+        )
+
+
+        
+        .def("get_antenna",&sink::get_antenna,       
+            py::arg("chan") = 0,
+            D(sink,get_antenna)
+        )
+
+
+        
+        .def("set_dc_offset",&sink::set_dc_offset,       
+            py::arg("offset"),
+            py::arg("chan") = 0,
+            D(sink,set_dc_offset)
+        )
+
+
+        
+        .def("set_iq_balance",&sink::set_iq_balance,       
+            py::arg("balance"),
+            py::arg("chan") = 0,
+            D(sink,set_iq_balance)
+        )
+
+
+        
+        .def("set_bandwidth",&sink::set_bandwidth,       
+            py::arg("bandwidth"),
+            py::arg("chan") = 0,
+            D(sink,set_bandwidth)
+        )
+
+
+        
+        .def("get_bandwidth",&sink::get_bandwidth,       
+            py::arg("chan") = 0,
+            D(sink,get_bandwidth)
+        )
+
+
+        
+        .def("get_bandwidth_range",&sink::get_bandwidth_range,       
+            py::arg("chan") = 0,
+            D(sink,get_bandwidth_range)
+        )
+
+
+        
+        .def("set_clock_source",&sink::set_clock_source,       
+            py::arg("source"),
+            py::arg("mboard") = 0,
+            D(sink,set_clock_source)
+        )
+
+
+        
+        .def("get_clock_source",&sink::get_clock_source,       
+            py::arg("mboard"),
+            D(sink,get_clock_source)
+        )
+
+
+        
+        .def("get_clock_sources",&sink::get_clock_sources,       
+            py::arg("mboard"),
+            D(sink,get_clock_sources)
+        )
+
         ;
 
 
diff --git a/python/bindings/source_python.cc b/python/bindings/source_python.cc
index 67863eabc0628c3528b877467901c450eacaa400..538b223099258e5d61bdc1ca70cdad88d200796c 100644
--- a/python/bindings/source_python.cc
+++ b/python/bindings/source_python.cc
@@ -14,7 +14,7 @@
 /* BINDTOOL_GEN_AUTOMATIC(0)                                                       */
 /* BINDTOOL_USE_PYGCCXML(0)                                                        */
 /* BINDTOOL_HEADER_FILE(source.h)                                        */
-/* BINDTOOL_HEADER_FILE_HASH(97f30d2966976cf7782299eb7f0e0c68)                     */
+/* BINDTOOL_HEADER_FILE_HASH(c4dc092bc6b7b67799ed07ebd52c561c)                     */
 /***********************************************************************************/
 
 #include <pybind11/complex.h>
@@ -30,20 +30,243 @@ namespace py = pybind11;
 void bind_source(py::module& m)
 {
 
-    using source    = gr::bladeRF::source;
+    using source    = ::gr::bladeRF::source;
 
 
-    py::class_<source,
+    py::class_<source, gr::hier_block2,
         std::shared_ptr<source>>(m, "source", D(source))
 
         .def(py::init(&source::make),
-           py::arg("args"),
+           py::arg("args") = "",
            D(source,make)
         )
         
 
 
 
+
+        
+        .def("get_num_channels",&source::get_num_channels,       
+            D(source,get_num_channels)
+        )
+
+
+        
+        .def("get_sample_rates",&source::get_sample_rates,       
+            D(source,get_sample_rates)
+        )
+
+
+        
+        .def("set_sample_rate",&source::set_sample_rate,       
+            py::arg("rate"),
+            D(source,set_sample_rate)
+        )
+
+
+        
+        .def("get_sample_rate",&source::get_sample_rate,       
+            D(source,get_sample_rate)
+        )
+
+
+        
+        .def("get_freq_range",&source::get_freq_range,       
+            py::arg("chan") = 0,
+            D(source,get_freq_range)
+        )
+
+
+        
+        .def("set_center_freq",&source::set_center_freq,       
+            py::arg("freq"),
+            py::arg("chan") = 0,
+            D(source,set_center_freq)
+        )
+
+
+        
+        .def("get_center_freq",&source::get_center_freq,       
+            py::arg("chan") = 0,
+            D(source,get_center_freq)
+        )
+
+
+        
+        .def("set_freq_corr",&source::set_freq_corr,       
+            py::arg("ppm"),
+            py::arg("chan") = 0,
+            D(source,set_freq_corr)
+        )
+
+
+        
+        .def("get_freq_corr",&source::get_freq_corr,       
+            py::arg("chan") = 0,
+            D(source,get_freq_corr)
+        )
+
+
+        
+        .def("get_gain_names",&source::get_gain_names,       
+            py::arg("chan") = 0,
+            D(source,get_gain_names)
+        )
+
+
+        
+        .def("get_gain_range",(osmosdr::gain_range_t (source::*)(size_t))&source::get_gain_range,       
+            py::arg("chan") = 0,
+            D(source,get_gain_range,0)
+        )
+
+
+        
+        .def("get_gain_range",(osmosdr::gain_range_t (source::*)(std::string const &, size_t))&source::get_gain_range,       
+            py::arg("name"),
+            py::arg("chan") = 0,
+            D(source,get_gain_range,1)
+        )
+
+
+        
+        .def("set_gain_mode",&source::set_gain_mode,       
+            py::arg("automatic"),
+            py::arg("chan") = 0,
+            D(source,set_gain_mode)
+        )
+
+
+        
+        .def("get_gain_mode",&source::get_gain_mode,       
+            py::arg("chan") = 0,
+            D(source,get_gain_mode)
+        )
+
+
+        
+        .def("set_gain",(double (source::*)(double, size_t))&source::set_gain,       
+            py::arg("gain"),
+            py::arg("chan") = 0,
+            D(source,set_gain,0)
+        )
+
+
+        
+        .def("set_gain",(double (source::*)(double, std::string const &, size_t))&source::set_gain,       
+            py::arg("gain"),
+            py::arg("name"),
+            py::arg("chan") = 0,
+            D(source,set_gain,1)
+        )
+
+
+        
+        .def("get_gain",(double (source::*)(size_t))&source::get_gain,       
+            py::arg("chan") = 0,
+            D(source,get_gain,0)
+        )
+
+
+        
+        .def("get_gain",(double (source::*)(std::string const &, size_t))&source::get_gain,       
+            py::arg("name"),
+            py::arg("chan") = 0,
+            D(source,get_gain,1)
+        )
+
+
+        
+        .def("set_if_gain",&source::set_if_gain,       
+            py::arg("gain"),
+            py::arg("chan") = 0,
+            D(source,set_if_gain)
+        )
+
+
+        
+        .def("set_bb_gain",&source::set_bb_gain,       
+            py::arg("gain"),
+            py::arg("chan") = 0,
+            D(source,set_bb_gain)
+        )
+
+
+        
+        .def("get_antennas",&source::get_antennas,       
+            py::arg("chan") = 0,
+            D(source,get_antennas)
+        )
+
+
+        
+        .def("set_antenna",&source::set_antenna,       
+            py::arg("antenna"),
+            py::arg("chan") = 0,
+            D(source,set_antenna)
+        )
+
+
+        
+        .def("get_antenna",&source::get_antenna,       
+            py::arg("chan") = 0,
+            D(source,get_antenna)
+        )
+
+
+        
+        .def("set_dc_offset_mode",&source::set_dc_offset_mode,       
+            py::arg("mode"),
+            py::arg("chan") = 0,
+            D(source,set_dc_offset_mode)
+        )
+
+
+        
+        .def("set_dc_offset",&source::set_dc_offset,       
+            py::arg("offset"),
+            py::arg("chan") = 0,
+            D(source,set_dc_offset)
+        )
+
+
+        
+        .def("set_iq_balance_mode",&source::set_iq_balance_mode,       
+            py::arg("mode"),
+            py::arg("chan") = 0,
+            D(source,set_iq_balance_mode)
+        )
+
+
+        
+        .def("set_iq_balance",&source::set_iq_balance,       
+            py::arg("balance"),
+            py::arg("chan") = 0,
+            D(source,set_iq_balance)
+        )
+
+
+        
+        .def("set_bandwidth",&source::set_bandwidth,       
+            py::arg("bandwidth"),
+            py::arg("chan") = 0,
+            D(source,set_bandwidth)
+        )
+
+
+        
+        .def("get_bandwidth",&source::get_bandwidth,       
+            py::arg("chan") = 0,
+            D(source,get_bandwidth)
+        )
+
+
+        
+        .def("get_bandwidth_range",&source::get_bandwidth_range,       
+            py::arg("chan") = 0,
+            D(source,get_bandwidth_range)
+        )
+
         ;