code: def inspect(self, source, preset=None, **options):
          
  
          # Start timer
          start = datetime.datetime.now()
  
          # Prepare preset
          preset = self.__get_source_preset(source, preset)
          if preset == 'nested':
              options['presets'] = self.__presets
              for s in source:
                  if s.get('preset') is None:
                      s['preset'] = self.__get_source_preset(s['source'])
  
          # Prepare tables
          preset_func = self.__get_preset(preset)['func']
          warnings, tables = preset_func(source, **options)
          if len(tables) > self.__table_limit:
              warnings.append(
                  'Dataset inspection has reached %s table(s) limit' %
                  (self.__table_limit))
              tables = tables[:self.__table_limit]
  
          # Collect table reports
          table_reports = []
          if tables:
              tasks = []
              pool = ThreadPool(processes=len(tables))
              try:
                  for table in tables:
                      tasks.append(pool.apply_async(self.__inspect_table, (table,)))
                  for task in tasks:
                      table_warnings, table_report = task.get()
                      warnings.extend(table_warnings)
                      table_reports.append(table_report)
              finally:
                  pool.terminate()
  
          # Stop timer
          stop = datetime.datetime.now()
  
          # Compose report
          report = {
              'time': round((stop - start).total_seconds(), 3),
              'valid': all(item['valid'] for item in table_reports),
              'error-count': sum(len(item['errors']) for item in table_reports),
              'table-count': len(tables),
              'tables': table_reports,
              'warnings': warnings,
              'preset': preset,
          }
  
          return report
docs: https://github.com/frictionlessdata/goodtables-py#inspector