class_docstr: A base class for data sources.
  
  This class represents a custom data source that allows for reading from and/or
  writing to it. The data source provides methods to create readers and writers
  for reading and writing data, respectively. At least one of the methods ``reader``
  or ``writer`` must be implemented by any subclass to make the data source either
  readable or writable (or both).
  
  After implementing this interface, you can start to load your data source using
  ``spark.read.format(...).load()`` and save data using ``df.write.format(...).save()``.
  
  .. versionadded: 4.0.0
docstr: Returns a ``DataSourceReader`` instance for reading data.
  
  The implementation is required for readable data sources.
  
  Parameters
  ----------
  schema : StructType
      The schema of the data to be read.
  
  Returns
  -------
  reader : DataSourceReader
      A reader instance for this data source.
code: def reader(self, schema: StructType) -> "DataSourceReader":
      """
      Returns a ``DataSourceReader`` instance for reading data.
  
      The implementation is required for readable data sources.
  
      Parameters
      ----------
      schema : StructType
          The schema of the data to be read.
  
      Returns
      -------
      reader : DataSourceReader
          A reader instance for this data source.
      """
      raise PySparkNotImplementedError(
          error_class="NOT_IMPLEMENTED",
          message_parameters={"feature": "reader"},
      )
  
imports: from abc import ABC, abstractmethod
  from collections import UserDict
  from typing import Any, Dict, Iterator, List, Sequence, Tuple, Type, Union, TYPE_CHECKING
  from pyspark.sql import Row
  from pyspark.sql.types import StructType
  from pyspark.errors import PySparkNotImplementedError
label_desc: Use image node_id 4 for calling the DataSource obj's underlying member method code with example usage: obj.reader(schema) without return types