diff --git a/Cargo.lock b/Cargo.lock
index 39bac2d..d075621 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -16,7 +16,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
 
 [[package]]
 name = "ffi-fundamentals"
-version = "0.1.0"
+version = "0.0.1-alpha.4"
 dependencies = [
  "fundamentals",
  "pyo3",
diff --git a/ffi/ffi-fundamentals/Cargo.toml b/ffi/ffi-fundamentals/Cargo.toml
index 2c69373..5163b5c 100644
--- a/ffi/ffi-fundamentals/Cargo.toml
+++ b/ffi/ffi-fundamentals/Cargo.toml
@@ -10,4 +10,4 @@ crate-type = ["cdylib"]
 
 [dependencies]
 fundamentals ={ path = "../../fundamentals", features = ["pyo3"] }
-pyo3 = "0.22"
\ No newline at end of file
+pyo3 = { version = "0.22", features = ["extension-module"] }
\ No newline at end of file
diff --git a/fundamentals/Cargo.toml b/fundamentals/Cargo.toml
index b798872..5cc5fc9 100644
--- a/fundamentals/Cargo.toml
+++ b/fundamentals/Cargo.toml
@@ -11,7 +11,7 @@ license = "MIT"
 
 [dependencies]
 fundamentals-derive = { version = "0.0.1-alpha.2" }
-pyo3 = { version = "0.22", optional = true }
+pyo3 = { version = "0.22", optional = true, features = [ "extension-module" ] }
 
 [dev-dependencies]
 hex = "0.4.3"
diff --git a/fundamentals/src/bitflag.rs b/fundamentals/src/bitflag.rs
index 1fdbbdd..084ba92 100644
--- a/fundamentals/src/bitflag.rs
+++ b/fundamentals/src/bitflag.rs
@@ -3,10 +3,14 @@
 //! Author: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>.
 use std::vec::Vec;
 
+#[cfg(feature = "pyo3")]
+use pyo3::pyclass;
+
 use crate::core::{FromWire, ToWire};
 
 // FIXME: rename to bitvector :)
-#[derive(Clone, Debug)]
+#[cfg_attr(feature = "pyo3", pyclass)]
+#[derive(Clone, Debug, Default)]
 pub struct BitFlag {
     pub len: u16,
     inner: Vec<u8>,
diff --git a/fundamentals/src/bolt/bolt1.rs b/fundamentals/src/bolt/bolt1.rs
index 8880b90..070409a 100644
--- a/fundamentals/src/bolt/bolt1.rs
+++ b/fundamentals/src/bolt/bolt1.rs
@@ -3,12 +3,12 @@ use std::io::{Read, Write};
 
 use fundamentals_derive::{DecodeWire, EncodeWire};
 #[cfg(feature = "pyo3")]
-use pyo3::pyclass;
+use pyo3::prelude::*;
 
 use crate::core::{FromWire, ToWire};
 use crate::prelude::*;
 
-#[cfg_attr(feature = "pyo3", pyclass)]
+#[cfg_attr(feature = "pyo3", pyclass(set_all))]
 #[derive(DecodeWire, EncodeWire, Debug, Clone)]
 pub struct Error {
     #[msg_type = 17]
@@ -17,7 +17,7 @@ pub struct Error {
     pub data: BitFlag,
 }
 
-#[cfg_attr(feature = "pyo3", pyclass)]
+#[cfg_attr(feature = "pyo3", pyclass(set_all))]
 #[derive(DecodeWire, EncodeWire, Debug, Clone)]
 pub struct Init {
     #[msg_type = 16]
@@ -27,7 +27,21 @@ pub struct Init {
     pub init_tlvs: Stream,
 }
 
-#[cfg_attr(feature = "pyo3", pyclass)]
+/// Python impl method to expose python API
+#[cfg_attr(feature = "pyo3", pymethods)]
+impl Init {
+    #[new]
+    fn new() -> PyResult<Self> {
+        Ok(Self {
+            ty: 16,
+            globalfeatures: BitFlag::default(),
+            features: BitFlag::default(),
+            init_tlvs: Stream::default(),
+        })
+    }
+}
+
+#[cfg_attr(feature = "pyo3", pyclass(set_all))]
 #[derive(DecodeWire, EncodeWire, Debug, Clone)]
 pub struct Ping {
     #[msg_type = 18]
@@ -36,7 +50,7 @@ pub struct Ping {
     pub ignored: BitFlag,
 }
 
-#[cfg_attr(feature = "pyo3", pyclass)]
+#[cfg_attr(feature = "pyo3", pyclass(set_all))]
 #[derive(DecodeWire, EncodeWire, Debug, Clone)]
 pub struct Pong {
     #[msg_type = 19]
@@ -44,7 +58,7 @@ pub struct Pong {
     pub ignored: BitFlag,
 }
 
-#[cfg_attr(feature = "pyo3", pyclass)]
+#[cfg_attr(feature = "pyo3", pyclass(set_all))]
 #[derive(DecodeWire, EncodeWire, Debug, Clone)]
 pub struct Warning {
     #[msg_type = 1]
diff --git a/fundamentals/src/tlv.rs b/fundamentals/src/tlv.rs
index 6038a55..b52fc08 100644
--- a/fundamentals/src/tlv.rs
+++ b/fundamentals/src/tlv.rs
@@ -30,13 +30,17 @@
 //! makes parsing faster and the data smaller than in comparable text based protocols.
 //!
 //! Author: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
+#[cfg(feature = "pyo3")]
+use pyo3::pyclass;
+
 use crate::core::{FromWire, ToWire};
 use crate::types::BigSize;
 
 /// Stream - A `tlv_stream` is a series of (possibly zero) `tlv_record`s, represented as the
 /// concatenation of the encoded `tlv_record`s. When used to extend existing
 /// messages, a `tlv_stream` is typically placed after all currently defined fields.
-#[derive(Clone)]
+#[cfg_attr(feature = "pyo3", pyclass)]
+#[derive(Clone, Default)]
 pub struct Stream {
     pub records: Vec<Record>,
 }
@@ -78,6 +82,7 @@ impl FromWire for Stream {
 /// * [`bigsize`: `type`]
 /// * [`bigsize`: `length`]
 /// * [`length`: `value`]
+#[cfg_attr(feature = "pyo3", pyclass)]
 #[derive(Clone)]
 pub struct Record {
     /// The `type` is encoded using the BigSize format. It functions as a