
    i                    6   S SK Jr  S SKrS SKJrJr   S SKJr  S SK	J
r
  S SKJr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Jr  SSKJr  Sr " S S5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rg! \ a	    S SKJr   N}f = f)    )annotationsN)AnyProtocol)Self)meta)	BaseModelValidationError   )DefaultCacheRenderCache)config)env)
AsyncError)ChatMessagechat_message_from_text)generate_canary_word0c                      \ rS rSrSSSSSS.             SS jjrSS jr\SS j5       r\SS j5       r\SS j5       r	\SS	 j5       r
\SS
 j5       rSS jrSrg)
BasePrompt   N)nameversionmetadatacanary_wordrender_cachec               J   U=(       d    0 U l         U=(       d    [        [        R                  " 5       5      U l        Xl        U=(       d
    [        5       U l        [        R                  " U5      U l
        U=(       d    [        U l        SU=(       d
    [        5       0U l        g)a  
Prompt constructor.

Parameters:
    text: The template text.
    name: The name to identify this prompt.
    version: The version string attached to this prompt.
    metadata: A key-value set of metadata pairs attached to this prompt.
    canary_word: The string to use for the `{{canary_word}}` extension. If `None`, a default string will be
        generated.
    render_cache: The caching backend to store rendered prompts. If `None`, the default in-memory backend will
        be used.
r   N)	_metadatastruuiduuid4_name_rawr   _render_cacher   from_string	_templateDEFAULT_VERSION_versionr   defaults)selftextr   r   r   r   r   s          F/home/james-whalen/.local/lib/python3.13/site-packages/banks/prompt.py__init__BasePrompt.__init__   sk    . "R.S.
	);\^.2?&(M7K7MN    c                <    Uc  U R                   $ XR                   -  $ Nr(   )r)   datas     r+   _get_contextBasePrompt._get_context<   s    <== mm##r.   c                    U R                   $ r0   )r   r)   s    r+   r   BasePrompt.metadataA   s    ~~r.   c                    U R                   $ r0   )r!   r6   s    r+   r   BasePrompt.nameE   s    zzr.   c                    U R                   $ )z#Returns the raw text of the prompt.)r"   r6   s    r+   rawBasePrompt.rawI   s     yyr.   c                    U R                   $ r0   )r'   r6   s    r+   r   BasePrompt.versionN   s    }}r.   c                n    [         R                  " U R                  5      n[        R                  " U5      $ r0   )r   parser;   r   find_undeclared_variables)r)   asts     r+   	variablesBasePrompt.variablesR   s%    ii!--c22r.   c                &    U R                   S   U;   $ )z^Returns whether the canary word is present in `text`, signalling the prompt might have leaked.r   r1   )r)   r*   s     r+   canary_leakedBasePrompt.canary_leakedW   s    }}]+t33r.   )r   r!   r"   r#   r%   r'   r(   )r*   r   r   
str | Noner   rH   r   dict[str, Any] | Noner   rH   r   zRenderCache | NonereturnNone)r2   zdict | NonerJ   dict)rJ   zdict[str, Any])rJ   r   )rJ   rH   )rJ   zset[str])r*   r   rJ   bool)__name__
__module____qualname____firstlineno__r,   r3   propertyr   r   r;   r   rC   rF   __static_attributes__ r.   r+   r   r      s    
  "*."&+/OO 	O
 O (O  O )O 
O@$
         3 34r.   r   c                  4    \ rS rSrSrSSS jjrSS	S jjrSrg)
Prompt\   a  
The `Prompt` class is the only thing you need to know about Banks on the Python side. The class can be
initialized with a string variable containing the prompt template text, then you can invoke the method `text`
on your instance to pass the data needed to render the template and get back the final prompt.

A quick example:
```py
from banks import Prompt


p = Prompt("Write a 500-word blog post on {{ topic }}.")
my_topic = "retrogame computing"
print(p.text({"topic": my_topic}))
```
Nc                    U R                  U5      nU R                  R                  U5      nU(       a  U$ U R                  R	                  U5      nU R                  R                  X5        U$ ){
Render the prompt using variables present in `data`

Parameters:
    data: A dictionary containing the context variables.
)r3   r#   getr%   rendersetr)   r2   cachedrendereds       r+   r*   Prompt.textm   s_       &##''-M--d3t.r.   c                   U R                  U5      nU R                  R                  U5      nU(       d6  U R                  R	                  U5      nU R                  R                  X5        / nUR                  5       R                  S5       H)  n UR                  [        R                  " U5      5        M+     U(       d  UR                  [        SUS95        U$ ! [         a     M\  f = f)rY   
user)rolecontent)r3   r#   rZ   r%   r[   r\   stripsplitappendr   model_validate_jsonr	   r   )r)   r2   r_   messageslines        r+   chat_messagesPrompt.chat_messages}   s       &%%))$/~~,,T2H""42&(NN$**40D ? ? EF 1  OO2QR # s   %C
C('C(rT   r0   r2   rI   rJ   r   )r2   rI   rJ   zlist[ChatMessage])rN   rO   rP   rQ   __doc__r*   rl   rS   rT   r.   r+   rV   rV   \   s       r.   rV   c                  >   ^  \ rS rSrSrSU 4S jjrSSS jjrSrU =r$ )	AsyncPrompt   a  
Banks provides async support through the machinery [provided by Jinja](https://jinja.palletsprojects.com/en/3.0.x/api/#async-support)

Since the Jinja environment is a global state in banks, the library can work either with or
without async support, and this must be known before importing anything.

If the application using banks runs within an `asyncio` loop, you can do two things
to optimize banks' execution:

1. Set the environment variable `BANKS_ASYNC_ENABLED=true`.
2. Use the `AsyncPrompt` class that has an awaitable `run` method.

For example, let's render a prompt that contains some calls to the `generate` extension. Those calls
will be heavily I/O bound, so other tasks can take advantage and advance while the prompt is being
rendered.

Example:
```python
# Enable async support before importing from banks
import os

os.environ["BANKS_ASYNC_ENABLED"] = "true"

# Show logs to see what's happening at runtime
import logging

logging.basicConfig(level=logging.INFO)

import asyncio
from banks import AsyncPrompt

prompt_template = """
Generate a tweet about the topic '{{ topic }}' with a positive sentiment.
"""

async def task(task_id: int, sleep_time: int):
    logging.info(f"Task {task_id} is running.")
    await asyncio.sleep(sleep_time)
    logging.info(f"Task {task_id} done.")


async def main():
    p = AsyncPrompt(prompt_template)
    # Schedule the prompt rendering along with two executions of 'task', one sleeping for 10 seconds
    # and one sleeping for 1 second
    results = await asyncio.gather(p.text({"topic": "AI frameworks"}), task(1, 10), task(2, 1))
    print("All tasks done, rendered prompt:")
    print(results[0])


asyncio.run(main())
```
c                j   > [         TU ]  " U0 UD6  [        R                  (       d  Sn[	        U5      eg )NzaAsync is not enabled. Please set the environment variable 'BANKS_ASYNC_ENABLED=on' and try again.)superr,   r   ASYNC_ENABLEDr   )r)   argskwargsmsg	__class__s       r+   r,   AsyncPrompt.__init__   s2    $)&)##uCS/! $r.   c                   #    U R                  U5      nU R                  R                  U5      nU(       a  U$ U R                  R	                  U5      I Sh  vN nU R                  R                  X5        U$  N!7f)rY   N)r3   r#   rZ   r%   render_asyncr\   r]   s       r+   r*   AsyncPrompt.text   sk        &##''-M"nn99$??t. @s   AA:A8"A:rT   )rv   r   rw   r   rJ   rK   r0   rn   )	rN   rO   rP   rQ   ro   r,   r*   rS   __classcell__)ry   s   @r+   rq   rq      s    4l" r.   rq   c                  <    \ rS rSrSrSS.S
S jjrSS.SS jjrS	rg)PromptRegistry   z:Interface to be implemented by concrete prompt registries.N)r   c                   g r0   rT   )r)   r   r   s      r+   rZ   PromptRegistry.get       sr.   F)	overwritec                   g r0   rT   )r)   promptr   s      r+   r\   PromptRegistry.set   r   r.   rT   )r   r   r   rH   rJ   rV   )r   rV   r   rM   rJ   rK   )rN   rO   rP   rQ   ro   rZ   r\   rS   rT   r.   r+   r   r      s    D6:J7<JJr.   r   c                  b    \ rS rSr% SrS\S'   SrS\S'   SrS\S'   SrS	\S
'   \	SS j5       r
Srg)PromptModel   z(Serializable representation of a Prompt.r   r*   NrH   r   r   rI   r   c                d    U " UR                   UR                  UR                  UR                  S9$ )N)r*   r   r   r   )r;   r   r   r   )clsr   s     r+   from_promptPromptModel.from_prompt   s&    

fnnW]WfWfggr.   rT   )r   z
type[Self]r   rV   rJ   r   )rN   rO   rP   rQ   ro   __annotations__r   r   r   classmethodr   rS   rT   r.   r+   r   r      s=    2
ID*GZ&*H#*h hr.   r   ) 
__future__r   r   typingr   r   r   ImportErrortyping_extensionsjinja2r   pydanticr   r	   cacher   r   r   r   errorsr   typesr   r   utilsr   r&   r   rV   rq   r   r   rT   r.   r+   <module>r      s    #   '  / ,    6 '>4 >4B;Z ;|L* L^KX K
h) 
hM  '&'s   B	 	BB