
    iO>                        S r SSKJr  SSKJrJrJrJrJr  SSK	J
r
  SSKJr  SSKJr  SSKJr  SS	KJr  SS
KJrJr  SSKJr  SSKJr  SSKJr  SSKJr  SSKJr  SSK J!r!  S r" " S S5      r#g)z Qiskit Runtime flexible session.    )annotations)DictOptionalTypeUnionAny)TracebackTypewraps)	BackendV2)QiskitRuntimeService   )RequestsApiError)IBMInputValueErrorIBMRuntimeError)RuntimeJobV2)ResultDecoder)
IBMBackendset_cm_session)hms_to_seconds)QiskitRuntimeLocalServicec                0   ^  [        T 5      U 4S j5       nU$ )z/Decorator used to ensure the session is active.c                T   > U R                   (       d  [        S5      eT" U /UQ70 UD6$ )NzThe session is closed.)_activer   )selfargskwargsfuncs      T/home/james-whalen/.local/lib/python3.13/site-packages/qiskit_ibm_runtime/session.py_wrapper!_active_session.<locals>._wrapper%   s+    ||!":;;D*4*6**    r
   )r   r!   s   ` r    _active_sessionr$   "   s"     4[+ +
 Or#   c                     \ rS rSrSr SSS.     SS jjjrSS.SS jjr\   S           SS jj5       rSS	 jr	SS
 jr
SS jrSS jrSS jrSS jr\SS j5       r\SS j5       r\SS j5       rS S jr        S!S jrSrg)"Session.   aV  Class for creating a Qiskit Runtime session.

A Qiskit Runtime ``session`` allows you to group a collection of iterative calls to
the quantum computer. A session is started when the first job within the session
is started. Subsequent jobs within the session are prioritized by the scheduler.

You can open a Qiskit Runtime session using this ``Session`` class and submit jobs
to one or more primitives.

For example::

    from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
    from qiskit.transpiler.preset_passmanagers import generate_preset_pass_manager
    from qiskit_ibm_runtime import QiskitRuntimeService, Session, SamplerV2 as Sampler

    service = QiskitRuntimeService()
    backend = service.least_busy(operational=True, simulator=False)

    # Bell Circuit
    qr = QuantumRegister(2, name="qr")
    cr = ClassicalRegister(2, name="cr")
    qc = QuantumCircuit(qr, cr, name="bell")
    qc.h(qr[0])
    qc.cx(qr[0], qr[1])
    qc.measure(qr, cr)

    pm = generate_preset_pass_manager(backend=backend, optimization_level=1)
    isa_circuit = pm.run(qc)

    with Session(backend=backend) as session:
        sampler = Sampler(mode=session)
        job = sampler.run([isa_circuit])
        pub_result = job.result()[0]
        print(f"Sampler job ID: {job.job_id()}")
        print(f"Counts: {pub_result.data.cr.get_counts()}")
NT
create_newc               p   SU l         SU l        SU l        SU l        SU l        [        U[        5      (       a  UR                  U l         Xl        OB[        U[        5      (       a  [        5       U l         Xl        O[        S[        U5       35      eUb  [        U[        5      (       a  UO[        US5      U l        [        U R                  [        5      (       aZ  U R                  R                  U l        U R                  R                  5       R                   (       d  U R#                  US9U l        ggg)aj  Session constructor.

Args:
    backend: Instance of ``Backend`` class.

    max_time:
        Maximum amount of time, a runtime session can be open before being
        forcibly closed. Can be specified as seconds (int) or a string like "2h 30m 40s".
        This value must be less than the
        `system imposed maximum
        <https://quantum.cloud.ibm.com/docs/guides/max-execution-time>`_.
    create_new: If True, the POST session API endpoint will be called to create a new session.
        Prevents creating a new session when ``from_id()`` is called.
Raises:
    ValueError: If an input value is invalid.
NTzInvalid backend type zInvalid max_time value: r(   )_service_backend	_instancer   _session_id
isinstancer   servicer   r   
ValueErrortypeintr   	_max_timeconfiguration	simulator_create_session)r   backendmax_timer)   s       r    __init__Session.__init__T   s    . UY-1gz**#OODM#M)--57DM#M4T']ODEE :h#<#< *DE 	 dmmZ00!]]44DN==..0::#'#7#7:#7#N  ; 1r#   c               $   [        U R                  [        5      (       aq  U(       aj  U R                  R                  U R                  5      R                  U R                  5       U R                  U R                  S5      nUR                  S5      $ g)zCreate a session.	dedicatedidN)	r/   r+   r   _get_api_clientr-   create_sessionr8   r4   get)r   r)   sessions      r    r7   Session._create_session   sd    dmm%9::zmm33DNNCRRG ;;t$$r#   c           
     t   U=(       d    0 nSU;  a  U R                   US'   U R                  US'   [        U R                  [        5      (       aM  U R                  R                  UUUU R                  SUUS9nU R                  c  UR                  5       U l        U$ U R                  R                  UUUUS9nU$ )aP  Run a program in the session.

Args:
    program_id: Program ID.
    inputs: Program input parameters. These input values are passed
        to the runtime program.
    options: Runtime options that control the execution environment.
    calibration_id: The calibration id to use with the program execution

Returns:
    Submitted job.
instancer8   F)
program_idoptionsinputs
session_idstart_sessionresult_decodercalibration_id)rF   rG   rH   rL   )r-   r,   r/   r+   r   _runr.   r8   )r   rF   rH   rG   rK   rL   jobs          r    rM   Session._run   s    * -RW$"&..GJ!]]	dmm%9::--$$%++#-- % C }}$ # 
 --$$%-	 % C 
r#   c                    SU l         U R                  (       a_  [        U R                  [        5      (       a?  U R                  R                  U R                  5      R                  U R                  5        ggg)z%Cancel all pending jobs in a session.FN)r   r.   r/   r+   r   r?   r-   cancel_sessionr   s    r    cancelSession.cancel   sS    
4==:N O OMM))$..9HHIYIYZ !Pr#   c                    SU l         U R                  (       a_  [        U R                  [        5      (       a?  U R                  R                  U R                  5      R                  U R                  5        ggg)zClose the session so new jobs will no longer be accepted, but existing
queued or running jobs will run to completion. The session will be terminated once there
are no more pending jobs.FN)r   r.   r/   r+   r   r?   r-   close_sessionrR   s    r    closeSession.close   sU     
4==:N O OMM))$..9GGHXHXY !Pr#   c                    U R                   (       aJ  U R                   R                  S:X  a  U R                   R                  $ U R                   R                  5       $ g)zZReturn backend for this session.

Returns:
    Backend for this session. None if unknown.
   N)r,   versionnamerR   s    r    r8   Session.backend   sA     ==)-)>)>!)C4==%%]I[I[I]]r#   c                    U R                  5       nU(       aI  US   nUS   nUS;   a  gUS:X  a  U(       d  US:X  a  gUS:X  a  U(       a  US:X  a  g	UR                  5       $ g
)a  Return current session status.

Returns:
    Session status as a string.

    * ``Pending``: Session is created but not active.
      It will become active when the next job of this session is dequeued.
    * ``In progress, accepting new jobs``: session is active and accepting new jobs.
    * ``In progress, not accepting new jobs``: session is active and not accepting new jobs.
    * ``Closed``: max_time expired or session was explicitly closed.
    * ``None``: status details are not available.
stateaccepting_jobs)openinactivePendingactivepending_inactivezIn progress, accepting new jobspending_closedz#In progress, not accepting new jobsN)details
capitalize)r   rg   r_   r`   s       r    statusSession.status   so     ,,.G$E$%56N,, !nBT9T8!.UFV=V<##%%r#   c                   U R                   (       au  [        U R                  [        5      (       aV  U R                  R	                  U R
                  5      R                  U R                   5      nU(       a  UR                  S5      $ g)zReturn session usage in seconds.

Session usage is the time from when the first job starts until the session goes inactive,
is closed, or when its last job completes, whichever happens last.

Batch usage is the amount of time all jobs spend on the QPU.
elapsed_timeNr.   r/   r+   r   r?   r-   session_detailsrA   r   responses     r    usageSession.usage   sa     
4==:N O O}}44T^^DTT  H ||N33r#   c                   U R                   (       GaH  [        U R                  [        5      (       Ga(  U R                  R	                  U R
                  5      R                  U R                   5      nU(       a  UR                  S5      UR                  S5      UR                  S5      UR                  S5      UR                  S5      UR                  S5      UR                  S5      UR                  S5      UR                  S	5      UR                  S
5      UR                  S5      UR                  S5      UR                  S5      UR                  S5      S.$ g)a  Return session details.

Returns:
    A dictionary with the sessions details.

    * ``id``: id of the session.
    * ``backend_name``: backend used for the session.
    * ``interactive_timeout``: The maximum idle time (in seconds) between jobs that
      is allowed to occur before the session is deactivated.
    * ``max_time``: Maximum allowed time (in seconds) for the session, subject to plan limits.
    * ``active_timeout``: The maximum time (in seconds) a session can stay active.
    * ``state``: State of the session - open, active, inactive, or closed.
    * ``accepting_jobs``: Whether or not the session is accepting jobs.
    * ``last_job_started``: Timestamp of when the last job in the session started.
    * ``last_job_completed``: Timestamp of when the last job in the session completed.
    * ``started_at``: Timestamp of when the session was started.
    * ``closed_at``: Timestamp of when the session was closed.
    * ``activated_at``: Timestamp of when the session state was changed to active.
    * ``mode``: Execution mode of the session.
    * ``usage_time``: The usage time, in seconds, of this Session or Batch.
      Usage is defined as the time a quantum system is committed to complete a job.
r>   backend_nameinteractive_ttlmax_ttl
active_ttlr_   r`   last_job_startedlast_job_completed
started_at	closed_atactivated_atmoderl   )r>   rt   interactive_timeoutr9   active_timeoutr_   r`   rx   ry   rz   r{   r|   r}   
usage_timeNrm   ro   s     r    rg   Session.details  s   . 
4==:N O O}}44T^^DTT  H ",,t,$,LL$@+3<<8I+J (Y 7&.ll<&@%\\'2&.ll3C&D(05G(H*2,,7K*L"*,,|"<!)k!:$,LL$@$LL0"*,,~">   r#   c                    U R                   $ )zUReturn the session ID.

Returns:
    Session ID. None if the backend is a simulator.
)r.   rR   s    r    rI   Session.session_id2  s     r#   c                    U R                   $ )zReturn service associated with this session.

Returns:
    :class:`qiskit_ibm_runtime.QiskitRuntimeService` associated with this session.
)r+   rR   s    r    r0   Session.service;  s     }}r#   c           	     b   UR                  5       n UR                  U5      nUR                  5       R                  U5      nUR                  S5      n	U	(       d  [        S5      eUR                  U	5      n
UR                  S5      nUR                  S5      nU R                  R                  5       S:X  a  S	OU R                  R                  5       nX:w  a  [        S
U SU SU S35      eU " U
SS9nUS:X  a  SUl        Xl        U$ ! [         a  nUR                  S:X  a  SnUR	                  5       R                  5        HA  u  pgXs:w  d  M  Uc  M   Xrl        UR                  U5      n  O! [         a  n SnAM;  SnAff = f   Uc  [        SUR                   35      Se SnAGNSnAff = f)a  Construct a Session object with a given ``session_id``. For example:

.. code-block::

    from qiskit_ibm_runtime import QiskitRuntimeService, Session
    service = QiskitRuntimeService()
    job = service.job(<job_id>)
    existing_session_id = job.session_id

    new_session = Session.from_id(existing_session_id, service)

Args:
    session_id: the id of the session to be created. This must be an already
        existing session id.
    service: instance of the ``QiskitRuntimeService`` class.

 Raises:
    IBMInputValueError: If given `session_id` does not exist.
    IBMRuntimeError: If the backend of the session is unknown.

Returns:
    A new Session with the given ``session_id``

i  NzSession not found: rt   z@The backend of this session is unknown. Try running a job first.r}   r_   rB   r=   z	Input ID z has execution mode z instead of .Fr(   closed)r?   rn   r   status_code_get_api_clientsitems_active_api_clientr   messagerA   r   r8   __name__lowerr   r.   )clsrI   r0   current_clientrp   exrE   client_rt   r8   r}   r_   
class_namerB   s                  r    from_idSession.from_idD  s   4 !002	[%55jAH **,<<ZH||N3!R  //,/||F#W%$'LL$6$6$8I$E[3<<K]K]K_
$J<';D6j\YZ[  g%0H#GO(C   	[~~$(/(@(@(B(H(H(J$H/H4H%9?6'-'='=j'IH!/ %$% )K #,/B2::,-OPVZZ	[sA   D 
F.8F)F)E-+F)-
F7F)=F!F))F.c                    [        U 5        U $ Nr   rR   s    r    	__enter__Session.__enter__  s    tr#   c                :    [        S 5        U R                  5         g r   )r   rW   )r   exc_typeexc_valexc_tbs       r    __exit__Session.__exit__  s     	t

r#   )r   r,   r-   r4   r+   r.   r   )r8   r   r9   zOptional[Union[int, str]]r)   Optional[bool])r)   r   returnOptional[str])NNN)rF   strrH   r   rG   zOptional[Dict]rK   zOptional[Type[ResultDecoder]]rL   r   r   r   )r   None)r   r   )r   zOptional[float])r   zOptional[Dict[str, Any]])r   r   )rI   r   r0   r   r   	'Session')r   r   )r   zOptional[Type[BaseException]]r   zOptional[BaseException]r   zOptional[TracebackType]r   r   )r   
__module____qualname____firstlineno____doc__r:   r7   r$   rM   rS   rW   r8   ri   rq   rg   propertyrI   r0   classmethodr   r   r   __static_attributes__ r#   r    r&   r&   .   s1   #P /3/O
 &*/O/O ,/O
 #/Ob ?C  
 #'8<(,00 0  	0
 60 &0 
0 0d[Z6 ,\       = =~/ ) (	
 
r#   r&   N)$r   
__future__r   typingr   r   r   r   r   typesr	   	functoolsr   qiskit.providers.backendr   qiskit_ibm_runtimer   api.exceptionsr   
exceptionsr   r   runtime_job_v2r   utils.result_decoderr   ibm_backendr   utils.default_sessionr   utils.convertersr   fake_provider.local_servicer   r$   r&   r   r#   r    <module>r      sH    ' " 3 3   . 3 , ; ( / # 1 , B	a ar#   