Skip to content

Releases: ravendb/ravendb-python-client

7.1.4 🎉

10 Dec 16:27
7e83006

Choose a tag to compare

7.1.4 continues the AI integration story: it adds GenAI Tasks (document-level AI processing), introduces structured prompts with ContentPart, and brings enhanced agent parameters with visibility control. This release syncs the Python client with RavenDB 7.1.4.

If you're new to AI in RavenDB, start here:

PyPi link: https://pypi.org/project/ravendb/7.1.4/


Highlights

GenAI Tasks

New GenAI Tasks let you automatically process documents with AI. Define a prompt, point it at a collection, and RavenDB handles the rest - calling the model, updating documents, and tracking progress.

from ravendb.documents.operations.ai import (
    GenAiConfiguration,
    GenAiTransformation,
    AddGenAiOperation,
)
from ravendb.documents.starting_point_change_vector import StartingPointChangeVector

# Configure the GenAI task
config = GenAiConfiguration(
    name="DocumentSummarizer",
    identifier="doc-summarizer",
    collection="Articles",
    connection_string_name="openai-connection",
    prompt="Summarize the following article",
    gen_ai_transformation=GenAiTransformation(script="ai.genContext({text: this.Content});"),
    update_script="this.Summary = $output.Summary;",
    sample_object='{"Summary": "A brief summary of the article"}',
    max_concurrency=4,
)

# Add the task and start processing documents
result = store.maintenance.send(AddGenAiOperation(config))
print(f"Task created with ID: {result.task_id}")

# Start from the beginning
result = store.maintenance.send(
    AddGenAiOperation(config, StartingPointChangeVector.BEGINNING_OF_TIME)
)

Full CRUD operations are available:

from ravendb.documents.operations.ongoing_tasks import (
    GetOngoingTaskInfoOperation,
    DeleteOngoingTaskOperation,
    OngoingTaskType,
)
from ravendb.documents.operations.ai import UpdateGenAiOperation

# Get task info
task = store.maintenance.send(
    GetOngoingTaskInfoOperation(result.task_id, OngoingTaskType.GEN_AI)
)

# Update task (with optional reset to reprocess documents)
config.prompt = "Updated prompt: Provide a detailed summary"
config.task_id = result.task_id
store.maintenance.send(UpdateGenAiOperation(result.task_id, config, reset=True))

# Delete task
store.maintenance.send(
    DeleteOngoingTaskOperation(result.task_id, OngoingTaskType.GEN_AI)
)

Structured Prompts with ContentPart

Prompts now support structured content parts for richer interactions:

from ravendb.documents.ai import TextPart, ContentPart
 
chat.add_user_prompt("Analyze this document")  # New method
chat.set_user_prompt("Analyze this document")  # Still works as before

# The prompt is internally converted to:
# [TextPart("Analyze this document")]

Enhanced Agent Parameters

Agent parameters now support descriptions and visibility control:

from ravendb.documents.operations.ai.agents import AiAgentConfiguration, AiAgentParameter

config = AiAgentConfiguration(
    identifier="my-agent",
    name="Customer Support Agent",
    system_prompt="You are helping {{user}}. Their account type is {{account_type}}.",
    parameters=[
        # Simple string (backward compatible)
        "user",
        # Full parameter with description and visibility
        AiAgentParameter(
            name="account_type",
            description="The customer's subscription tier",
            send_to_model=False, 
        ),
    ],
)

When send_to_model=False, the parameter value is substituted into the prompt but not exposed in echo messages or other model interactions, which is useful for sensitive data.


Reasoning Tokens & Usage Tracking

AiUsage now tracks reasoning tokens (for models that use chain-of-thought):

result = chat.run("response")
print(f"Reasoning tokens: {result.usage.reasoning_tokens}")
print(f"Total tokens: {result.usage.total_tokens}")

# Calculate usage difference between turns
diff = AiUsage.get_usage_difference(current_usage, previous_usage)

PR

(yeah, singular)

Full Changelog: 7.1.3...7.1.4

7.1.3 🎉

21 Nov 00:09
71607f3

Choose a tag to compare

Starting with 7.1.2, the Python client gained full AI Agents support.

7.1.3 takes that further: it syncs the API with RavenDB 7.1.3, smooths out the Agent experience (streaming, action handling, metrics), and adds connection string operations (including Vertex AI) plus a bunch of reliability fixes.

If you’re new to Agents, start here:

PyPi link: https://pypi.org/project/ravendb/7.1.3/

Highlights

AI Agents

  • New stream(...) method lets you push Agent responses to your UI as they arrive, ChatGPT-style.
  • You can register actions via conventient API and decide what happens when the model calls something you didn’t wire up, using handle(...), receive(...) and on_unhandled_action.
  • AI conversation run() returns rich stats (token usage, elapsed time, etc.) inside AiAnswer.
    ai_agent_result = store.ai.add_or_update_agent(ai_agent_configuration)

    ai_agent = store.ai.get_agents(ai_agent_result.identifier)

    chat = store.ai.conversation(
        ai_agent.ai_agents[0].identifier,
        "chats/",
        AiConversationCreationOptions(expiration_in_sec=3600).add_parameter("user", "users/15-A")
    )
    chat.on_unhandled_action = lambda args: print(f"Unhandled action: {args.action.name}")

    # Handle SendNotification action tool request
    chat.handle(
        "SendNotification",
        lambda args: f"Notification sent to {args['recipients']}", # mock sending notification
        AiHandleErrorStrategy.SEND_ERRORS_TO_MODEL,
    )

    while True:
        chat.set_user_prompt(input())

        def _on_chunk(answer: str):
            print(answer, end="")

        result = chat.stream("response", _on_chunk)
        print(result.usage)
        print(result.elapsed)

Vertex AI connection strings

You can now configure Vertex AI as an AI connection string, side-by-side with OpenAI and others:

cs_name = "vertex-demo"

vertex = VertexSettings(
    model="gemini-1.5-pro",
    google_credentials_json='{"project_id":"demo-vertex-project"}',
    location="us-central1",
    ai_version=VertexAIVersion.V1,
)

ai_cs = AiConnectionString(
    name=cs_name,
    identifier=cs_name,
    vertex_settings=vertex,
    model_type=AiModelType.CHAT,
)

store.maintenance.send(PutConnectionStringOperation(ai_cs))

Later you can point your AI Agent configuration at connection_string_name="vertex-demo" and talk to Vertex via the same Agents API.


Connection String CRUD (including AI)

New operations let you Add / Update / Get / Delete all connection string types (including AI ones), plus a dedicated RemoveConnectionStringByNameOperation that matches other SDKs.

Minimal CRUD example:

# Put
store.maintenance.send(PutConnectionStringOperation(ai_cs))

# Get single AI connection string
get_result = store.maintenance.send(
    GetConnectionStringsOperation(cs_name, ConnectionStringType.AI)
)
ai_map = get_result.ai_connection_strings
ai_cs_loaded = ai_map[cs_name]

# Remove by name
store.maintenance.send(
    RemoveConnectionStringByNameOperation(ConnectionStringType.AI, cs_name)
)

Fixes

  • Fix: zstd-compression module prevented storing the data by yh-0 #254
  • Topology & network error handling by @redknightlois #249

PRs

  • README.md should use order_by_descending() by @Scooletz in #246
  • RDBC-935 Add Connection String Operations by @yh-0 in #247
  • RDBC-949: Refactors is_read_request to a method by @redknightlois in #250
  • RDBC-948: Ensure topology handling matches C# Client. by @redknightlois in #249
  • RDBC-940 v7.1 Zstd-compression data prevents simple store. by @yh-0 in #251
  • RDBC-964 Fix SSLError in https test by @yh-0 in #256
  • RDBC-954 Python client: fix Connection String R/W Bugs (OLAP + AI) by @yh-0 in #255
  • RDBC-934 Sync to 7.1.3 by @poissoncorp in #258
  • RDBC-934 7.1.3 C# API parity by @poissoncorp in #259

7.1.2 - RavenDB AI Agents in Python 🎉

27 Aug 15:10
4e383d9

Choose a tag to compare

Starting v7.1.2, the RavenDB Python client ships with the AI Agents API. This way you can spin up safe, tool-driven agents right from your Python app.

If you haven’t seen what our Agents are or why we built them, grab 2 minutes and read the feature announcement (it’s genuinely good):

👉 AI Agents Feature Announcement: ravendb/ravendb#21249
👉 AI Agents Documentation: https://docs.ravendb.net/ai-integration/ai-agents/ai-agents-api


Usage example (create → chat → handle actions)

from ravendb import DocumentStore, AiAgentConfiguration, AiAgentToolAction

# 1) Connect
store = DocumentStore(["http://localhost:8080"], "AwesomeDatabase")
store.initialize()

# 2) Define an agent (connection string configured in RavenDB Studio)
agent = AiAgentConfiguration(
    name="orders-manager-test",
    connection_string_name="OpenAI",
    system_prompt="You help users with their orders and can email results."
)
agent.sample_object = '{"answer":"text"}'

# Optional: let the agent request supervised actions
send_email = AiAgentToolAction(
    name="SendEmail",
    description="Send an email with provided content to the given address."
)
send_email.parameters_sample_object = '{"Address":"user@example.com","EmailContent":"text"}'
agent.actions.append(send_email)

agent_id = store.ai.add_or_update_agent(agent).identifier

# 3) Run a conversation
with store.ai.conversation(agent_id) as chat:
    chat.set_user_prompt("Send message 'Raven on Python has agents now lmao' to josh@example.com.")
    result = chat.run()

    # 4) If the agent requested an action, handle it and reply with the result
    if result.action_requests:
        for action in result.action_requests:
            if action.name == "SendEmail":
                # ...your app actually sends the email here...
                chat.add_action_response(action.tool_id, "email sent ✅")

        # Continue the conversation after fulfilling actions
        result = chat.run()

    print("Agent says:", result.response)

Which results in:

Agent says: {'answer': 'The message has been sent to josh@example.com!'}

That’s the core loop. The API also supports parameters, query tools, persistence, and chat-trimming see the README examples:
https://github.com/ravendb/ravendb-python-client/blob/v7.1/AI_AGENT_README.md

Enjoy, happy coding! 🤖💙

7.0.2

30 May 14:57
7159ea6

Choose a tag to compare

Python Client 7.0.2 is out 🐍🚀

It delivers powerful streaming capabilities, AI Integration query API, plus a fix for handling emojis

  • New: Document and Query Streaming API – stream large result sets efficiently 🔄📄
  • New: AI Integration's using_task support in vector search – vector queries using AI Embedding Generation Tasks 🤖🧠
  • Fix: Better error parsing in RequestExecutor for smoother debugging 🛠️
  • Fix: 🐛 UTF-8 encoding added to document data – your emojis are safe now 💾📦

New Contributors

  • 👏 @yh-0 implemented streaming support (#238)
  • 👏 @MohKamal improved emoji handling with UTF-8 encoding (#239)

Feel free to join our Discord Community & discuss the release here: https://discord.gg/ravendb 💬🧑‍💻


💡 Highlight: AI Integration using_task

Perform semantic search using AI Embeddings Generation:

q = session.query(object_type=Dto).vector_search_text_using_task("EmbeddingField", "fishing", "my-ai-task")

Also supports variants:

  • vector_search_text_i1_using_task(...)
  • vector_search_text_i8_using_task(...)
  • All with optional is_exact=True

RavenDB Embeddings Generation docs here.


🚿 Streaming API: Lightweight Queries at Scale

Stream documents, queries, raw queries, and even query statistics without loading all results into memory:

✅ Stream a normal query

query = session.query(object_type=Color)
stream = session.advanced.stream(query)
for result in stream:
    print(result.document.name)

✅ Stream a raw RQL query

raw_query = session.advanced.raw_query("from Colors where is_primary = true", object_type=Color)
stream = session.advanced.stream(raw_query)
for result in stream:
    print(result.document.name)

✅ Stream with statistics

def stats_callback(stats):
    print(f"Total results: {stats.total_results}")

query = session.query(object_type=Color).where_equals("is_primary", True)
stream = session.advanced.stream_with_statistics(query, stats_callback)
for result in stream:
    print(result.document.name)

✅ Stream documents by ID prefix

stream = session.advanced.stream_starting_with("colors/", object_type=Color)
for result in stream:
    print(result.document.name)

PRs

  • RDBC-893 Fix parsing of errors inside RequestExecutor._handle_unsuccessful_response by @poissoncorp (#236)
  • RDBC-900 Add usingTask to Python Vector Search API by @poissoncorp (#237)
  • RDBC-670 Streaming by @yh-0 (#238)
  • Add UTF-8 encoding to document data by @MohKamal (#239)

Full Changelog: 7.0.0...7.0.2

7.0.0

12 Feb 12:37
b644192

Choose a tag to compare

Python Client 7.0 is here 🐍⚡

  • Added Vector Search API, for AI & ML integrations 🦾🤖 (PR)
  • Added SearchEngineType to IndexDefinition - allows creating Corax static indexes 🐦‍⬛📊
  • Bugfixes, operations, more helper methods

Merged PRs worth mentioning

  • RDBC-822 Fix FacetOptions serialization by @poissoncorp in #214
  • RDBC-817 Implement query.projection() by @poissoncorp in #215
  • RDBC-843 Add GetDetailedCollectionStatisticsOperation by @poissoncorp in #217
  • RDBC-845 Implement AddDatabaseNodeOperation by @poissoncorp in #218
  • RDBC-851 Attachments bulk insert doesn't drop concurrency lock after store by @poissoncorp in #219
  • RDBC-844 Implement database settings operations by @poissoncorp in #222
  • RDBC-847 Implement documentStore.Maintenance.Server.ForNode by @poissoncorp in #223
  • RDBC-848 Implement session.Advanced.SessionInfo.SetContext by @poissoncorp in #224
  • RDBC-837/838 Move has_changes and ignore_changes_for to session.advanced by @poissoncorp in #225
  • RDBC-839 Use find_identity_property - implement get identity property by @poissoncorp in #226
  • RDBC-833 Implement session.advanced.get_current_session_node by @poissoncorp in #227

Full Changelog: 5.2.6...7.0.0

5.2.6 ⚡

07 Mar 12:47
40b1baf

Choose a tag to compare

Breaking changes 🔥

Session methods - lazily.load() and include().load() - #210

  • set object_type argument as optional
  • inverted the object_type and key arguments order
  • lazily.load() now takes a list of str document IDs, not *ids

'Id' property won't be stored at the server anymore - #211

  • Document id is still available as a value of the Id property, but the value is set after serialization
  • Documents loaded as dict objects won't contain the Id key (still available via session.advanced.get_metadata_for(...)["@id"] or session.advanced.get_document_id())
  • Custom from_json methods that have been setting the Id property should skip that step, as the Id property will be set to a valid value after the serialization

What's new 🌬️

  • Added include time series API to subscription includes builder
  • Storing a dict-document while providing document id collection prefix (e.g. session.store({"Name":"Graziano"}, "Users/"}) stores the document under valid collection (e.g. Users), not "dicts"
  • Made object_type argument in get_compare_exchange_values() optional
  • Fixed load_starting_with_into_stream() and made it return bytes stream, instead of passing it as an argument to be modified within the method itself
  • Marked object_type argument as optional in many methods across the API
  • Fixed a bug that caused an error when disposing uninitialized RequestExecutor
  • Improved session.time_series_for() error messages

5.2.5

09 Feb 11:11
8f552ab

Choose a tag to compare

What's New

  • Ensured full compatibility with RavenDB 6.0.x ⚡
  • Time Series
  • Creation of a document with server-generated GUID (#199)
  • Revisions (#201)
    • Configuration
    • Crud
    • Force revision creation
  • Bulk insert (#202)
    • Counters bulk insert
    • Time series bulk insert
  • HTTPS
    • Secured changes API (#204)
  • Multiple new useful operations & commands (#200, #203)
    • ResetIndexOperation
    • GetStatisticsOperation
    • DeleteIndexErrorsOperation
    • CreateSampleDataOperation
    • ConfigureExpirationOperation
    • ReorderDatabaseMembersOperation
    • PromoteDatabaseNodeOperation
    • NextIdentityForOperation
    • SeedIdentityForOperation
    • CompactDatabaseOperation
    • ExplainQueryCommand
    • GetIdentitiesOperation
    • ToggleDatabasesStateOperation
    • PutSortersOperation
    • DeleteSorterOperation
    • PutServerWideAnalyzersOperation
    • DeleteServerWideAnalyzerOperation
    • PutServerWideBackupConfigurationOperation
    • GetServerWideBackupConfigurationsOperation
    • GetServerWideBackupConfigurationOperation
    • DeleteServerWideTaskOperation
    • UpdateDocumentsCompressionConfigurationOperation
    • GetLogsConfigurationOperation
    • SetLogsConfigurationOperation
    • SetDatabasesLockOperation
    • PutServerWideSortersOperation
    • DeleteServerWideSorterOperation

Breaking changes 💔

  • Changed method name in spatial options - GeographySpatialOptionsFactory.quad_prefix_tree_level to quad_prefix_tree_index - 243b292
  • Removed duplicated FacetTermSortMode - here
  • aggregate_by_facets now takes a list of Facets - 02346f5

Improved typehints for:

  • LoaderWithInclude.load()
  • attachments.store()
  • session.advanced.attachments.get()

Minor fixes for:

  • Facets queries
  • Spatial queries

The client is now being tested using Embedded RavenDB Server as a package!
https://github.com/ravendb/ravendb-python-embedded
It's a great tool for so many scenarios!

Full Changelog: 5.2.4...5.2.5

5.2.4

18 May 08:00
8309c40

Choose a tag to compare

Available here https://pypi.org/project/ravendb/5.2.4/

5.2.3

17 Apr 08:30
2179ca3

Choose a tag to compare

Available here https://pypi.org/project/ravendb/5.2.3/

5.2.2

03 Mar 14:33
dd3fd60

Choose a tag to compare

Available here https://pypi.org/project/ravendb/5.2.2/