ravendb-embedded starts a real RavenDB server as a child process of your Python application.
The server starts with your code, stops with it, and is accessed through the standard ravendb
client.
Use it for local development, integration tests, or applications that should manage their own RavenDB process.
pip install ravendb-embeddedPython 3.10+ is required.
The default mode uses the RavenDB binaries included in the wheel and a compatible system .NET runtime:
from ravendb_embedded import EmbeddedServer, ServerOptions
options = ServerOptions()
with EmbeddedServer() as server:
server.start_server(options)
with server.get_document_store("MyDatabase") as store:
with store.open_session() as session:
session.store({"name": "Ayende"}, "people/1")
session.save_changes()| Mode | System .NET required? | Server lifecycle | Best for |
|---|---|---|---|
| Bundled server | Yes | Managed by the package | The simplest local setup |
| On-demand self-contained server | No | Downloaded, cached, and managed by the package | Portable developer and CI environments |
| Self-contained server you provide | No | Managed by the package | Offline or centrally controlled server artifacts |
Only the bundled-server mode requires .NET to be installed on the machine running Python.
The wheel includes a framework-dependent RavenDB server. Its runtime requirement follows the RavenDB version:
ravendb-embedded version |
Required runtime |
|---|---|
| 7.2.x | .NET 10 |
| 7.1.x | .NET 8 |
Run dotnet --list-runtimes and look for Microsoft.NETCore.App. Re-check this requirement when
upgrading to a new RavenDB minor version.
Runnable walkthrough: Lab 01 — embedded zero-config.
For the same managed experience without installing .NET, let the package download a self-contained RavenDB build:
from ravendb_embedded import EmbeddedServer, ServerOptions
options = ServerOptions()
options.with_auto_downloaded_server()
options.data_directory = "./data/RavenDB"
options.logs_path = "./logs/RavenDB"
with EmbeddedServer() as server:
server.start_server(options)
with server.get_document_store("MyDatabase") as store:
...The operating system and architecture are detected at runtime, so the same Python configuration is portable across:
- Windows x64 and x86
- Linux x64 and ARM64
- macOS x64 and ARM64
Unsupported targets, including Windows ARM64, fail with an explicit error instead of downloading an incompatible build.
The first run downloads a self-contained server (100 MB+) and caches it under
~/.cache/ravendb-embedded. Later runs reuse that cache. Pass cache_root to
with_auto_downloaded_server() when you want a different location:
options.with_auto_downloaded_server(cache_root="./.ravendb-cache")By default, the download follows the installed package's RavenDB version line. The cache is not refreshed automatically; remove that version's cache directory when you intentionally want to resolve a newer server build from the same line.
The wheel does not contain a self-contained build for every platform; it downloads only the build needed by the current machine. Self-contained mode removes the system .NET requirement, but normal RavenDB operating-system dependencies still apply. Minimal Linux images may need their distribution's ICU package.
Runnable walkthrough: Lab 03 — on-demand server.
Download and extract the Server package for the target platform, then point the package at its
Server directory:
from ravendb_embedded import EmbeddedServer, ServerOptions
options = ServerOptions()
options.with_external_server("/path/to/extracted/Server")
with EmbeddedServer() as server:
server.start_server(options)
with server.get_document_store("MyDatabase") as store:
...The native apphost is run directly, so dotnet is not called. Server packages are available on
the RavenDB downloads page.
Runnable walkthrough: Lab 02 — external self-contained server.
with_external_server() also accepts a ZIP archive containing RavenDB server files. Applications
that ship the archive as a Python package resource can use
ExtractFromPkgResourceServerProvider(package, resource_name). For other sources, implement
ProvideRavenDBServer.provide(target_directory) and assign the provider to options.provider.
Create a ServerOptions instance before starting the server:
Construct options with ServerOptions(). The misleading ServerOptions.INSTANCE() constructor
alias is deprecated and will be removed in a future release.
data_directory: where database data is stored; retains the existing<package-directory>/RavenDBdefault. Set it explicitly for applications that need a writable or application-owned location.logs_path: where RavenDB writes its logs; defaults to<data_directory>/Logsand follows a changeddata_directoryuntil you setlogs_pathexplicitly.accept_eula: controls the RavenDB EULA command-line setting and defaults toTrue.server_url: address to bind; the default uses localhost and a free port.dot_net_path: path todotnetfor bundled mode when it is not onPATH.command_line_args: additional RavenDB server arguments.framework_version: defaults to"", preserving the dotnet host's normal runtime selection and roll-forward behavior. Set it toautoto read the server runtime configuration and select a compatible installed patch, or set an exact version for advanced setups.graceful_shutdown_timeout: how long to wait before terminating the child process.process_kill_timeout: how long to wait for the process after terminating or killing it.max_server_startup_time_duration: maximum server startup time.
Startup failures raise ServerStartupError. When the configured startup duration expires, the
more specific ServerStartupTimeoutError is raised. A failed start does not dispose the
EmbeddedServer; correct the configuration and call start_server() on the same instance again.
from datetime import timedelta
from ravendb_embedded import EmbeddedServer, ServerOptions, ServerStartupTimeoutError
options = ServerOptions()
options.max_server_startup_time_duration = timedelta(seconds=15)
with EmbeddedServer() as server:
try:
server.start_server(options)
except ServerStartupTimeoutError:
options.max_server_startup_time_duration = timedelta(minutes=1)
server.start_server(options)accept_eula remains enabled by default. Applications can configure it through
options.accept_eula. See the
RavenDB EULA for the applicable terms.
Configure a license through options.licensing:
options.licensing.license = '{"Id": "..."}' # Inline license JSON
# Or:
options.licensing.license_path = "/path/to/license.json"
options.licensing.disable_auto_update = True
options.licensing.disable_auto_update_from_api = True
options.licensing.disable_license_support_check = True
options.licensing.throw_on_invalid_or_missing_license = TrueThe fail-fast option is useful in CI and production environments where falling back to an unlicensed server would hide a configuration problem.
Use ServerOptions.secured() with a server PFX to start RavenDB over HTTPS:
options = ServerOptions()
options.secured("server.pfx")This configures the embedded server only. External clients must authenticate with a certificate
trusted by RavenDB. To let EmbeddedServer create authenticated DocumentStore instances, supply
a client PEM as well:
options = ServerOptions()
options.secured(
"server.pfx",
"client.pem",
server_pfx_certificate_password="",
ca_certificate_path="ca.crt",
)The returned DocumentStore receives the client certificate and custom CA automatically.
The client PEM must contain both its certificate and matching unencrypted private key. If the
certificate declares Extended Key Usage, it must include TLS Client Authentication.
The server PFX is not reused as a client certificate: a server-only certificate may
not have Client Authentication EKU, and its PFX may not contain a suitable client identity.
ca_certificate_path is optional for certificates trusted by the operating system; provide a CA
bundle for private or self-signed server certificates. A supplied client PEM and CA bundle are
validated before the RavenDB process starts.
When another process supplies the server certificate, use secured_with_certificate_exec():
options.secured_with_certificate_exec(
certificate_exec="python",
certificate_arguments='"load_certificate.py" "server.pfx"',
client_pem_certificate_path="client.pem",
ca_certificate_path="ca.crt",
)The certificate command must write the PFX bytes to standard output.
Runnable walkthrough: Lab 04 — secured embedded server.
Use get_server_process_id() to inspect the child process. stop_server() stops RavenDB without
disposing the EmbeddedServer, and restart_server() starts it again with the same options.
Calling close() stops the process and disposes all document stores.
The public API is synchronous, matching the RavenDB Python client's execution model. Server start,
shutdown, and restart calls block until the requested lifecycle transition completes. Async
applications can run these blocking lifecycle calls with asyncio.to_thread() instead of
maintaining a second embedded API with different behavior.
EmbeddedServer is intentionally not a singleton. An application may run independent server
instances in the same Python process; give each instance a different data_directory and
logs_path. Prefer with EmbeddedServer() as server: so the context manager always closes that
instance's process and document stores.
first_options = ServerOptions()
first_options.data_directory = "./servers/first"
second_options = ServerOptions()
second_options.data_directory = "./servers/second"
with EmbeddedServer() as first, EmbeddedServer() as second:
first.start_server(first_options)
second.start_server(second_options)
assert first.get_server_process_id() != second.get_server_process_id()Register a process-exit callback when the application needs to observe server failures:
server.add_server_process_exited(
lambda event: print(event.process_id, event.exit_code, event.expected)
)Callbacks run on a background thread. event.expected is True for exits caused by
stop_server(), restart_server(), or close(), and False when the child exits unexpectedly.
Runnable walkthrough: Lab 06 — lifecycle and process monitoring.
The default data directory remains RavenDB inside the installed package directory. Set
data_directory explicitly when the package directory may be read-only, the application owns its
storage layout, or several embedded servers run in one process. Use a temporary directory for
disposable tests.
Runnable walkthrough: Lab 05 — persistent data.
get_document_store(database_name) returns a standard RavenDB DocumentStore and creates the
database when needed. For finer control, create DatabaseOptions with
DatabaseOptions.from_database_name() and call get_document_store_from_options().
Set skip_creating_database=True on DatabaseOptions when the database is managed elsewhere.
Call open_studio_in_browser() to open RavenDB Studio.
The repository contains runnable, self-checking examples:
| Lab | Scenario | Needs system .NET? |
|---|---|---|
| 01 | Bundled zero-config server | Yes |
| 02 | Self-contained server you provide | No |
| 03 | Automatic platform detection, download, and cache | No |
| 04 | HTTPS and client-certificate authentication | Yes |
| 05 | Data that survives server restarts | Yes |
| 06 | Stop, restart, PID, and process-exit monitoring | Yes |
The scripts live in the repository rather than the installed wheel. Clone or download the repository, install the package, and run them from the repository root. See the complete labs guide.