# This file was auto-generated by Fern from our API Definition.

import typing

from ..core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ..core.request_options import RequestOptions
from ..types.calibration_response import CalibrationResponse
from ..types.job import Job
from ..types.job_status_response import JobStatusResponse
from ..types.page_response_job import PageResponseJob
from ..types.service_execution_id import ServiceExecutionId
from .raw_client import AsyncRawJobsClient, RawJobsClient
from .types.create_job_request_input import CreateJobRequestInput
from .types.create_job_request_input_format import CreateJobRequestInputFormat
from .types.create_job_request_input_params import CreateJobRequestInputParams

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


class JobsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._raw_client = RawJobsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> RawJobsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        RawJobsClient
        """
        return self._raw_client

    def search_jobs(
        self,
        *,
        page: typing.Optional[int] = None,
        size: typing.Optional[int] = None,
        sort: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PageResponseJob:
        """
        Get quantum jobs with pagination.

        Parameters
        ----------
        page : typing.Optional[int]
            Zero-based page index (0..N)

        size : typing.Optional[int]
            The size of the page to be returned

        sort : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        PageResponseJob
            The page of quantum jobs matching the query.

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.search_jobs(
            service_execution_id="X-Service-Execution-Id",
            page=1,
            size=1,
        )
        """
        _response = self._raw_client.search_jobs(
            page=page, size=size, sort=sort, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    def create_job(
        self,
        *,
        backend_id: str,
        shots: int,
        input: CreateJobRequestInput,
        name: typing.Optional[str] = OMIT,
        input_format: typing.Optional[CreateJobRequestInputFormat] = OMIT,
        input_params: typing.Optional[CreateJobRequestInputParams] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Job:
        """
        Create a new quantum job.

        Parameters
        ----------
        backend_id : str
            Identifier of the backend the job should be executed on

        shots : int
            Number of shots to execute

        input : CreateJobRequestInput
            Backend-specific job input. The format depends on the backend the job is executed on.

        name : typing.Optional[str]
            Optional name for the job

        input_format : typing.Optional[CreateJobRequestInputFormat]
            The input format of the input (e.g. QASM string). The input format must match the backend's capabilities. If not specified, the default format for the backend is assumed.

        input_params : typing.Optional[CreateJobRequestInputParams]
            Backend-specific job input parameters. The supported parameters depend on the backend the job is executed on.

        tags : typing.Optional[typing.Sequence[str]]
            Set of tags to identify or categorize the job

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Job
            The created job.

        Examples
        --------
        from planqk import AzureIonqJobInputCircuitItem, GeneratedPlanqkQuantumClient
        from planqk.jobs import CreateJobRequestInput_AzureIonqSimulator

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.create_job(
            backend_id="aws.sim.sv1",
            shots=1000,
            input=CreateJobRequestInput_AzureIonqSimulator(
                circuit=[
                    AzureIonqJobInputCircuitItem(
                        targets=[0],
                    ),
                    AzureIonqJobInputCircuitItem(
                        targets=[1],
                        controls=[0],
                    ),
                ],
                qubits=2,
            ),
        )
        """
        _response = self._raw_client.create_job(
            backend_id=backend_id,
            shots=shots,
            input=input,
            name=name,
            input_format=input_format,
            input_params=input_params,
            tags=tags,
            request_options=request_options,
        )
        return _response.data

    def get_job(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Job:
        """
        Get a quantum job's details.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Job
            The job details.

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.get_job(
            id="id",
            service_execution_id="X-Service-Execution-Id",
        )
        """
        _response = self._raw_client.get_job(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    def cancel_job(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Cancel the execution of a quantum job.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.cancel_job(
            id="id",
            service_execution_id="X-Service-Execution-Id",
        )
        """
        _response = self._raw_client.cancel_job(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    def get_job_status(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> JobStatusResponse:
        """
        Get a quantum job's status.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        JobStatusResponse
            The job's status.

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.get_job_status(
            id="id",
            service_execution_id="X-Service-Execution-Id",
        )
        """
        _response = self._raw_client.get_job_status(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    def get_job_result(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Any]:
        """
        Get a quantum job's results.

        Parameters
        ----------
        id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Dict[str, typing.Any]
            The job's result.

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.get_job_result(
            id="id",
        )
        """
        _response = self._raw_client.get_job_result(id, request_options=request_options)
        return _response.data

    def get_job_result_stream(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[ServiceExecutionId] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.Iterator[bytes]:
        """
        Get the result of a specific job as json file.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[ServiceExecutionId]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.Iterator[bytes]
            The job result content as json file

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.get_job_result_stream(
            id="id",
        )
        """
        with self._raw_client.get_job_result_stream(
            id, service_execution_id=service_execution_id, request_options=request_options
        ) as r:
            yield from r.data

    def get_job_input(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> str:
        """
        Get the input.json of a quantum job.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        str
            The job's input.

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.get_job_input(
            id="id",
            service_execution_id="X-Service-Execution-Id",
        )
        """
        _response = self._raw_client.get_job_input(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    def get_calibration_of_job_backend(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CalibrationResponse:
        """
        Get the calibration of a specific backend.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CalibrationResponse
            The job's calibration.

        Examples
        --------
        from planqk import GeneratedPlanqkQuantumClient

        client = GeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )
        client.jobs.get_calibration_of_job_backend(
            id="id",
            service_execution_id="X-Service-Execution-Id",
        )
        """
        _response = self._raw_client.get_calibration_of_job_backend(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data


class AsyncJobsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._raw_client = AsyncRawJobsClient(client_wrapper=client_wrapper)

    @property
    def with_raw_response(self) -> AsyncRawJobsClient:
        """
        Retrieves a raw implementation of this client that returns raw responses.

        Returns
        -------
        AsyncRawJobsClient
        """
        return self._raw_client

    async def search_jobs(
        self,
        *,
        page: typing.Optional[int] = None,
        size: typing.Optional[int] = None,
        sort: typing.Optional[typing.Union[str, typing.Sequence[str]]] = None,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> PageResponseJob:
        """
        Get quantum jobs with pagination.

        Parameters
        ----------
        page : typing.Optional[int]
            Zero-based page index (0..N)

        size : typing.Optional[int]
            The size of the page to be returned

        sort : typing.Optional[typing.Union[str, typing.Sequence[str]]]
            Sorting criteria in the format: property,(asc|desc). Default sort order is ascending. Multiple sort criteria are supported.

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        PageResponseJob
            The page of quantum jobs matching the query.

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.search_jobs(
                service_execution_id="X-Service-Execution-Id",
                page=1,
                size=1,
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.search_jobs(
            page=page, size=size, sort=sort, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    async def create_job(
        self,
        *,
        backend_id: str,
        shots: int,
        input: CreateJobRequestInput,
        name: typing.Optional[str] = OMIT,
        input_format: typing.Optional[CreateJobRequestInputFormat] = OMIT,
        input_params: typing.Optional[CreateJobRequestInputParams] = OMIT,
        tags: typing.Optional[typing.Sequence[str]] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Job:
        """
        Create a new quantum job.

        Parameters
        ----------
        backend_id : str
            Identifier of the backend the job should be executed on

        shots : int
            Number of shots to execute

        input : CreateJobRequestInput
            Backend-specific job input. The format depends on the backend the job is executed on.

        name : typing.Optional[str]
            Optional name for the job

        input_format : typing.Optional[CreateJobRequestInputFormat]
            The input format of the input (e.g. QASM string). The input format must match the backend's capabilities. If not specified, the default format for the backend is assumed.

        input_params : typing.Optional[CreateJobRequestInputParams]
            Backend-specific job input parameters. The supported parameters depend on the backend the job is executed on.

        tags : typing.Optional[typing.Sequence[str]]
            Set of tags to identify or categorize the job

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Job
            The created job.

        Examples
        --------
        import asyncio

        from planqk import (
            AsyncGeneratedPlanqkQuantumClient,
            AzureIonqJobInputCircuitItem,
        )
        from planqk.jobs import CreateJobRequestInput_AzureIonqSimulator

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.create_job(
                backend_id="aws.sim.sv1",
                shots=1000,
                input=CreateJobRequestInput_AzureIonqSimulator(
                    circuit=[
                        AzureIonqJobInputCircuitItem(
                            targets=[0],
                        ),
                        AzureIonqJobInputCircuitItem(
                            targets=[1],
                            controls=[0],
                        ),
                    ],
                    qubits=2,
                ),
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.create_job(
            backend_id=backend_id,
            shots=shots,
            input=input,
            name=name,
            input_format=input_format,
            input_params=input_params,
            tags=tags,
            request_options=request_options,
        )
        return _response.data

    async def get_job(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> Job:
        """
        Get a quantum job's details.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        Job
            The job details.

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.get_job(
                id="id",
                service_execution_id="X-Service-Execution-Id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_job(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    async def cancel_job(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> None:
        """
        Cancel the execution of a quantum job.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        None

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.cancel_job(
                id="id",
                service_execution_id="X-Service-Execution-Id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.cancel_job(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    async def get_job_status(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> JobStatusResponse:
        """
        Get a quantum job's status.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        JobStatusResponse
            The job's status.

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.get_job_status(
                id="id",
                service_execution_id="X-Service-Execution-Id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_job_status(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    async def get_job_result(
        self, id: str, *, request_options: typing.Optional[RequestOptions] = None
    ) -> typing.Dict[str, typing.Any]:
        """
        Get a quantum job's results.

        Parameters
        ----------
        id : str

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        typing.Dict[str, typing.Any]
            The job's result.

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.get_job_result(
                id="id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_job_result(id, request_options=request_options)
        return _response.data

    async def get_job_result_stream(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[ServiceExecutionId] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> typing.AsyncIterator[bytes]:
        """
        Get the result of a specific job as json file.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[ServiceExecutionId]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration. You can pass in configuration such as `chunk_size`, and more to customize the request and response.

        Returns
        -------
        typing.AsyncIterator[bytes]
            The job result content as json file

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.get_job_result_stream(
                id="id",
            )


        asyncio.run(main())
        """
        async with self._raw_client.get_job_result_stream(
            id, service_execution_id=service_execution_id, request_options=request_options
        ) as r:
            async for _chunk in r.data:
                yield _chunk

    async def get_job_input(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> str:
        """
        Get the input.json of a quantum job.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        str
            The job's input.

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.get_job_input(
                id="id",
                service_execution_id="X-Service-Execution-Id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_job_input(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data

    async def get_calibration_of_job_backend(
        self,
        id: str,
        *,
        service_execution_id: typing.Optional[str] = None,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> CalibrationResponse:
        """
        Get the calibration of a specific backend.

        Parameters
        ----------
        id : str

        service_execution_id : typing.Optional[str]

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        CalibrationResponse
            The job's calibration.

        Examples
        --------
        import asyncio

        from planqk import AsyncGeneratedPlanqkQuantumClient

        client = AsyncGeneratedPlanqkQuantumClient(
            organizationid="YOUR_ORGANIZATIONID",
            api_key="YOUR_API_KEY",
        )


        async def main() -> None:
            await client.jobs.get_calibration_of_job_backend(
                id="id",
                service_execution_id="X-Service-Execution-Id",
            )


        asyncio.run(main())
        """
        _response = await self._raw_client.get_calibration_of_job_backend(
            id, service_execution_id=service_execution_id, request_options=request_options
        )
        return _response.data
