@patch.dict(
"os.environ",
{
"AWS_ACCESS_KEY_ID": "AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY": "AWS_SECRET_ACCESS_KEY",
"AWS_SESSION_TOKEN": "AWS_SESSION_TOKEN",
"AWS_REGION_NAME": "aws-region-name",
"AWS_S3_INPUT_PATH": "AWS_S3_INPUT_PATH",
"AWS_S3_BUCKET": "AWS_S3_BUCKET",
"AWS_ENDPOINT": "AWS_ENDPOINT",
},
)
@override_settings(
AWS_ACCESS_KEY_ID="AWS_ACCESS_KEY_ID",
AWS_SECRET_ACCESS_KEY="AWS_SECRET_ACCESS_KEY",
AWS_SESSION_TOKEN="AWS_SESSION_TOKEN",
AWS_REGION_NAME="aws-region-name",
AWS_S3_INPUT_PATH="AWS_S3_INPUT_PATH",
AWS_S3_BUCKET="AWS_S3_BUCKET",
AWS_ENDPOINT="AWS_ENDPOINT",
)
@patch.dict("sys.modules", {package + ".minio_connector": MagicMock()})
@patch.dict("sys.modules", {"time": MagicMock()})
def test_doctr(self):
# ~~~~~~~~~~~~~~~~~~ Arrange ~~~~~~~~~~~~~~~~~~
from botocore.response import StreamingBody
from .doctr import DoctrFromS3, Document
from .minio_connector import MinIOConnector as minio_mock


    expected_pages = ["page1", "page2", "page3"]
    minio_mock.return_value.read_from_s3.return_value = self.get_pdf(
        expected_pages, True
    )

    s3_mock = Mock()
    sagemaker_mock = Mock()
    s3_mock.upload_fileobj.return_value = None
    sagemaker_mock.invoke_endpoint_async.return_value = {
        "OutputLocation": "s3://AWS_S3_BUCKET/AWS_S3_OUTPUT"
    }

    content = (b'{"asdf": "1", "qwer": "2"}')  # ###########################
    fake_raw_stream = io.BytesIO(content)
    content_length = len(content)
    mock_body = StreamingBody(fake_raw_stream, content_length)
    s3_mock.get_object.return_value = {"Body": mock_body}

    mock_page1 = MagicMock()
    mock_page1.render.return_value = expected_pages[0]
    mock_page2 = MagicMock()
    mock_page2.render.return_value = expected_pages[1]
    mock_page3 = MagicMock()
    mock_page3.render.return_value = expected_pages[2]
    mock_document_instance = Document(pages=[mock_page1, mock_page2, mock_page3])
    #Document.from_dict.return_value = mock_document_instance

    patcher = patch.object(Document, 'from_dict', return_value=mock_document_instance)
    mock_from_dict = patcher.start()  # Activates the patch

    # ~~~~~~~~~~~~~~~~~~ Act ~~~~~~~~~~~~~~~~~~
    doctr = DoctrFromS3()
    doctr.s3_client = s3_mock
    doctr.sagemaker_client = sagemaker_mock
    pages = doctr.extract_text("s3://test/FILENAME")  # s3://test

    # ~~~~~~~~~~~~~~~~~~ Assert ~~~~~~~~~~~~~~~~~~
    s3_mock.assert_called_once_with("s3")
    sagemaker_mock.assert_called_once_with("sagemaker-runtime")
    s3_mock.upload_fileobj.assert_called_once_with(
        minio_mock.return_value.read_from_s3.return_value,
        "AWS_S3_BUCKET",
        "AWS_S3_INPUT_PATH/FILENAME",
        ExtraArgs={"ContentType": "application/pdf"},
    )
    sagemaker_mock.invoke_endpoint_async.assert_called_once_with(
        EndpointName="AWS_ENDPOINT",
        InputLocation="s3://AWS_S3_BUCKET/AWS_S3_INPUT_PATH/FILENAME",
    )
    s3_mock.get_object.assert_called_once_with(
        Bucket="AWS_S3_BUCKET", Key="AWS_S3_OUTPUT"
    )

    #mock_from_dict.assert_called_once_with(mock_body.read())  # ###########################
    #for page in result.pages:  # ###########################
    #    page.render.assert_called_once()

    self.assertEqual("\n".join(expected_pages), pages)
    # requests_mock.reset_mock()

    patcher.stop()
the code above gives error:
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)

the code which needs to have a mock test is :


def extract_text(self, minio_path):
    file_name = minio_path.split("/")[-1]

    n_tries = 5
    wait_sec = 5

    file_stream = MinIOConnector(minio_path).read_from_s3()

    for n_try in range(n_tries):
        try:
            logger.info(f"AWS S3 upload... (try {n_try+1})")

            path = os.path.join(settings.AWS_S3_INPUT_PATH, file_name)
            self.s3_client.upload_fileobj(
                file_stream,
                settings.AWS_S3_BUCKET,
                path,
                ExtraArgs={"ContentType": "application/pdf"},
            )

            self.s3_client.get_waiter("object_exists").wait(
                Bucket=settings.AWS_S3_BUCKET, Key=path
            )
            aws_s3_path = f"s3://{settings.AWS_S3_BUCKET}/{settings.AWS_S3_INPUT_PATH}/{file_name}"

            logger.info("AWS S3 upload... done!")
            break
        except Exception as e:
            logger.warning(f"AWS S3 upload error: {repr(e)}")
            logger.info(
                f"AWS S3 upload sleeping for {wait_sec} seconds before trying again"
            )
            time.sleep(wait_sec)
    else:
        logger.error(f"AWS S3 upload limit of maximum tries reached ({n_tries})")
        raise ConnectionError("Could not connect to AWS S3")

    for n_try in range(n_tries):
        try:
            logger.info(f"Invoke SageMaker endpoint... (try {n_try+1})")

            response = self.sagemaker_client.invoke_endpoint_async(
                EndpointName=settings.AWS_ENDPOINT,  # 'doctr-endpoint-10-12-2024'
                InputLocation=aws_s3_path,
                # CustomAttributes=json.dumps({'pages' : '1-3,5,100'}),  ############
            )

            logger.info("Invoke SageMaker endpoint... done!")
            break
        except Exception as e:
            logger.warning(f"Invoke SageMaker endpoint error: {repr(e)}")
            logger.info(
                f"Invoke SageMaker endpoint sleeping for {wait_sec} seconds before trying again"
            )
            time.sleep(wait_sec)
    else:
        logger.error(
            f"Invoke SageMaker endpoint limit of maximum tries reached ({n_tries})"
        )
        raise ConnectionError("Could not connect to SageMaker endpoint")

    url = urllib.parse.urlparse(response["OutputLocation"])
    bucket, key = url.netloc, url.path[1:]

    self.s3_client.get_waiter("object_exists").wait(
        Bucket=bucket,
        Key=key,
        WaiterConfig={
            "Delay": 5,
            "MaxAttempts": (15 * 60) / 5,  # 15 mins with a try at every 5 secs
        },
    )

    logger.info(f"asdf type: {type(self.s3_client.get_object(Bucket=bucket, Key=key)["Body"].read())}")

    result = json.loads(
        self.s3_client.get_object(Bucket=bucket, Key=key)["Body"].read()
    )
    #logger.info(f"result type: {type(result)}")
    #logger.info(f"result: {result}")
    x = Document.from_dict(save_dict=result)
    #logger.info(f"doc type: {type(x)}")
    #logger.info(f"doc: {x}")
    return x.render()
how do i solve the error?