diff --git a/src/py/libcamera/pymain.cpp b/src/py/libcamera/pymain.cpp
index c442ad50..6375e326 100644
--- a/src/py/libcamera/pymain.cpp
+++ b/src/py/libcamera/pymain.cpp
@@ -250,15 +250,34 @@ PYBIND11_MODULE(_libcamera, m)
 		.def_property_readonly("id", &Camera::id)
 		.def("acquire", &Camera::acquire)
 		.def("release", &Camera::release)
-		.def("start", [](Camera &self) {
+		.def("start", [](Camera &self, py::dict controls) {
 			self.requestCompleted.connect(handleRequestCompleted);
 
-			int ret = self.start();
+			const ControlInfoMap &controlMap = self.controls();
+			ControlList controlList(controlMap);
+			for (const auto& [hkey, hval]: controls) {
+				auto key = hkey.cast<std::string>();
+
+				auto it = find_if(controlMap.begin(), controlMap.end(),
+						  [&key](const auto &kvp) {
+							  return kvp.first->name() == key; });
+
+				if (it == controlMap.end())
+					throw runtime_error("Control " + key + " not found");
+
+				const auto &id = it->first;
+				auto obj = py::cast<py::object>(hval);
+
+				controlList.set(id->id(), PyToControlValue(obj, id->type()));
+			}
+
+			int ret = self.start(&controlList);
 			if (ret)
 				self.requestCompleted.disconnect(handleRequestCompleted);
 
 			return ret;
-		})
+		},
+		py::arg("controls") = py::dict())
 
 		.def("stop", [](Camera &self) {
 			int ret = self.stop();
