docs: def generate(self, output_path=None, in_memory=False):
          """Executes the Statik project generator.
  
          Args:
              output_path: The path to which to write output files.
              in_memory: Whether or not to generate the results in memory. If True, this will
                  generate the output result as a dictionary. If False, this will write the output
                  to files in the output_path.
  
          Returns:
              If in_memory is True, this returns a dictionary containing the actual generated static
              content. If in_memory is False, this returns an integer indicating the number of files
              generated in the output path.
          """
          result = dict() if in_memory else 0
          logger.info("Generating Statik build...")
          try:
              if output_path is None and not in_memory:
                  raise InternalError(
                      "If project is not to be generated in-memory, an output path must be specified"
                  )
  
              self.error_context.update(filename=self.config_file_path)
              self.config = self.config or StatikConfig(self.config_file_path)
  
              if self.config.encoding is not None:
                  logger.debug("Using encoding: %s", self.config.encoding)
              else:
                  logger.debug("Using encoding: %s", self.config.encoding)
              self.error_context.clear()
  
              self.models = self.load_models()
              self.template_engine = StatikTemplateEngine(self)
  
              if self.config.external_database is not None:
                  self.config.external_database.write_files(output_path, self.models)
  
              self.views = self.load_views()
              if not self.views:
                  raise NoViewsError()
  
              self.db = self.load_db_data(self.models)
              self.project_context = self.load_project_context()
  
              in_memory_result = self.process_views()
  
              if in_memory:
                  result = in_memory_result
              else:
                  # dump the in-memory output to files
                  file_count = self.dump_in_memory_result(in_memory_result, output_path)
                  logger.info('Wrote %d output file(s) to folder: %s', file_count, output_path)
                  # copy any assets across, recursively
                  self.copy_assets(output_path)
                  result = file_count
              
              logger.info("Success!")
  
          except StatikError as exc:
              logger.debug(traceback.format_exc())
              logger.error(exc.render())
              # re-raise the error to stop execution
              raise exc
          
          except Exception as exc:
              logger.debug(traceback.format_exc())
              _exc = StatikError(
                  message="Failed to build project. Run Statik in verbose mode (-v) to see " +
                      "additional traceback information about this error.",
                  orig_exc=exc,
                  context=self.error_context
              )
              logger.error(_exc.render())
              raise _exc
  
          finally:
              try:
                  # make sure to destroy the database engine (to provide for the possibility of
                  # database engine reloads when watching for changes)
                  if self.db is not None:
                      self.db.shutdown()
  
              except Exception as e:
                  logger.exception("Unable to clean up properly: %s", e)
  
          return result