I did something like you want, but with C++ as start point:
C++ code creates python-like module with C functions.
After that C++ code runs target python module, that invokes functions from python-like module.
As result, python module is running and is invoking C++ functions.
Here the sample of C++ code:
// Sample of C++ function, which python module invokes
static PyObject* OutDtmf(PyObject* self, PyObject* args)
{
  PyObject* a1;
  if (PyArg_UnpackTuple(args, "OutDtmf", 1, 1, &a1))
  {
    // Check the result
    PyObject* astr = PyUnicode_AsUTF8String(a1);
    const char* ustr = PyBytes_AsString(astr);
    OutDtmf(ustr);
  }
  Py_RETURN_NONE;
}
// Pack of definitions
// --------------------
static PyMethodDef WarSysMethods[] = {
  { "Finish", FinishScript, METH_VARARGS, NULL },
  { "KpsoSetControl", KpsoSetControl, METH_VARARGS, NULL },
  { "KpsoSetLine", KpsoSetLine, METH_VARARGS, NULL },
  { "OutDtmf", OutDtmf, METH_VARARGS, NULL },
  { "PsoSetLine", PsoSetLine, METH_VARARGS, NULL},
  { NULL, NULL, 0 , nullptr }
};
static struct PyModuleDef WarSysModuleDef = {
  PyModuleDef_HEAD_INIT,
  "WarSys",
  NULL,
  -1,
  WarSysMethods };
PyMODINIT_FUNC PyInit_WarSys(void)
{
  PyObject *module;
  module = PyModule_Create(&WarSysModuleDef);
  return module;
}
// Start point for creation of python-like module and loading target python module
void StartScript(bool serverMode, const char* testModuleName)
{
  // Initialization Python -> C++
  PyImport_AppendInittab("WarSys", PyInit_WarSys);
  // Initialization C++ -> Python
  Py_Initialize();
  PyObject* pDict; // borrowed
  TestModule = PyImport_ImportModule(testModuleName);
  if (!TestModule)
  {
    PyErr_Print();
    return;
  }
  pDict = PyModule_GetDict(TestModule);
  // Read function objects
  FuncInit = PyDict_GetItemString(pDict, "Init");
....................
// Invokes python function in module (f.e. Init)
PyObject_CallObject(command.Function, command.Arguments)
in python code use:
import WarSys
and invokes functions WarSys.Finish(False) or other.