Server API¶
The ArcadeDBServer class enables HTTP API access and the Studio web interface for managing and querying ArcadeDB databases. Perfect for interactive exploration, debugging, and web applications.
Overview¶
The server provides:
- HTTP REST API: Query databases via HTTP endpoints
- Studio Web UI: Visual database exploration and query editor
- Multi-database Management: Create and access multiple databases
- Remote Access: Access from other applications via HTTP
When to Use Server Mode:
- Interactive development and debugging
- Web applications needing HTTP API
- Visual data exploration via Studio
- Remote database access
- Clients written in other languages that speak HTTP
When to Use Embedded Mode:
- Python-only applications
- Maximum performance (no HTTP overhead)
- Simplified deployment
- Reduced memory footprint
Module Function¶
create_server(root_path="./databases", root_password=None, config=None)¶
Create an ArcadeDB server instance.
Parameters:
root_path(str): Root directory for databases (default:"./databases")- All databases will be created under this directory
- Automatically created if it doesn't exist
root_password(Optional[str]): Root user password (default:None)- Strongly recommended for production
- At least 8 characters
- If
Noneon a freshroot_path(no root user stored yet),start()prompts for the root password on stdin, which blocks a script or service. There is no default password.
config(Optional[Dict[str, Any]]): Configuration dictionary (default:None)http_port(int): HTTP API port (default: 2480)host(str): Host to bind to (default: "localhost"). Pass "0.0.0.0" explicitly to expose the server on all IPv4 interfaces, or "::" for all IPv6 interfaces.mode(str): Server mode: "development", "test", or "production" (default: "development"). See Mode Comparison- Additional ArcadeDB configuration keys (see Advanced Configuration)
Returns:
ArcadeDBServer: Server instance (not started)
Example:
import arcadedb_embedded as arcadedb
# Basic server (development)
server = arcadedb.create_server(root_password="password123")
# Custom root path and password
server = arcadedb.create_server(
root_path="./my_databases",
root_password="my_secure_password123"
)
# Custom configuration
server = arcadedb.create_server(
root_path="./dbs",
root_password="secret123",
config={
"http_port": 8080,
"host": "127.0.0.1",
"mode": "production"
}
)
ArcadeDBServer Class¶
Constructor¶
ArcadeDBServer(
root_path: str = "./databases",
root_password: Optional[str] = None,
config: Optional[Dict[str, Any]] = None,
jvm_kwargs: Optional[dict] = None,
)
Prefer using create_server() function instead, unless you need jvm_kwargs.
Parameters:
root_path,root_password,config: As forcreate_server(), with one difference: the constructor usesroot_pathas given, whilecreate_server()first makes it absolute.jvm_kwargs(Optional[dict]): Keyword arguments forstart_jvm(), for example{"heap_size": "8g"}.create_server()has no such parameter, so this is the way to pass JVM options when the server is the first thing to start the JVM. Once the JVM is running, options that differ from the ones it started with raiseArcadeDBError.
start()¶
Start the ArcadeDB server and begin listening for connections.
Raises:
ArcadeDBError: If server is already started or fails to start
Example:
import arcadedb_embedded as arcadedb
server = arcadedb.create_server(root_password="password123")
server.start()
print(f"Server running at: {server.get_studio_url()}")
# ... do work ...
server.stop()
stop()¶
Stop the ArcadeDB server and release resources.
Note: It's safe to call even if server isn't started.
Example:
server = arcadedb.create_server(root_password="password123")
server.start()
try:
# Do work
pass
finally:
server.stop() # Always stop to clean up
is_started() -> bool¶
Check if the server is currently running.
Returns:
bool:Trueif server is running,Falseotherwise
Example:
server = arcadedb.create_server(root_password="password123")
print(server.is_started()) # False
server.start()
print(server.is_started()) # True
server.stop()
print(server.is_started()) # False
get_database(name: str) -> Database¶
Get an existing database from the server.
Parameters:
name(str): Database name
Returns:
Database: Database instance
Raises:
ArcadeDBError: If server not started or database doesn't exist
Example:
server = arcadedb.create_server(root_password="password123")
server.start()
# Get existing database
db = server.get_database("mydb")
# Use database
result = db.query("sql", "SELECT FROM Person")
for record in result:
print(record.to_dict())
db.close()
server.stop()
create_database(name: str) -> Database¶
Create a new database on the server.
Parameters:
name(str): Database name- Alphanumeric and underscores recommended
- Will be created under
root_path/databases/{name}/
Returns:
Database: New database instance
Raises:
ArcadeDBError: If server not started or creation fails
Example:
server = arcadedb.create_server(root_password="password123")
server.start()
# Create new database
db = server.create_database("products_db")
# Create schema
db.command("sql", "CREATE DOCUMENT TYPE Product")
db.command("sql", "CREATE PROPERTY Product.name STRING")
db.command("sql", "CREATE PROPERTY Product.price DECIMAL")
db.close()
server.stop()
Important: This method properly registers the database with the server, making it immediately visible in Studio UI.
get_http_port() -> int¶
Get the HTTP port the server is listening on.
Returns:
int: HTTP port number
Example:
get_studio_url() -> str¶
Get the full URL for the Studio web interface.
Returns:
str: Studio URL (e.g.,"http://localhost:2480/")
Example:
server = arcadedb.create_server(root_password="password123")
server.start()
print(f"Open Studio at: {server.get_studio_url()}")
# Open Studio at: http://localhost:2480/
Context Manager Support¶
The server supports Python context managers for automatic start/stop:
import arcadedb_embedded as arcadedb
with arcadedb.create_server(root_password="password123") as server:
# Server automatically started
db = server.create_database("temp_db")
db.command("sql", "CREATE DOCUMENT TYPE Test")
# Use database
with db.transaction():
db.command("sql", "INSERT INTO Test SET value = ?", 42)
db.close()
# Server automatically stopped when exiting 'with' block
Configuration Options¶
Basic Configuration¶
config = {
"http_port": 2480, # HTTP API port
"host": "localhost", # Bind address (default loopback; "0.0.0.0" = all IPv4 interfaces)
"mode": "development", # "development", "test", or "production"
}
server = arcadedb.create_server(config=config)
Mode Comparison¶
| Behaviour | "development" |
"test" |
"production" |
|---|---|---|---|
| Studio web UI | Served | Served | Not served, unless "studio_enabled": True (arcadedb.studio.enabled) |
detail (cause chain) in HTTP error bodies |
Included | Included | Omitted |
| Log level for user-triggered request errors | INFO | FINE | FINE |
| Log level for internal faults | SEVERE | WARNING | WARNING |
WAL flush default (arcadedb.txWalFlush) |
Unchanged | Unchanged | Set to 1 at start unless set explicitly |
OpenCypher LOAD CSV from file: URLs (arcadedb.opencypher.loadCsv.allowFileUrls) |
Unchanged | Unchanged | Disabled at start unless set explicitly |
The two production defaults are set on the process-wide configuration, so a database
the same Python process opens afterwards inherits them too. Production mode also logs a
checklist of settings at startup. A server in production mode serves no Studio page, so
get_studio_url() points at nothing there unless Studio is re-enabled.
Recommendation: Use "development" for local dev, "production" for deployment.
Advanced Configuration¶
You can pass any ArcadeDB configuration via the config dict:
config = {
"http_port": 8080,
"mode": "production",
# Additional ArcadeDB settings (with _ instead of ., camelCase kept)
"server_databaseDirectory": "./custom_dbs",
"server_httpSessionExpireTimeout": 30, # seconds
}
server = arcadedb.create_server(config=config)
Note: Python uses underscores (_), which are automatically converted to dots (.) for Java config keys. Keep the camelCase of the Java name:
server_httpSessionExpireTimeout→arcadedb.server.httpSessionExpireTimeout
A key that names no ArcadeDB setting is stored and ignored without an error.
Logging Configuration¶
ArcadeDB writes logs to multiple locations:
1. Application Logs¶
Location: ./log/arcadedb.log.* (relative to working directory)
Content: Server startup, database operations, errors
Cannot be changed (hardcoded in Java)
2. Server Event Logs¶
Location: {root_path}/log/server-event-log-*.jsonl
Content: HTTP requests, connections, events
Example: ./databases/log/server-event-log-20240115-093000.0.jsonl
(server-event-log-YYYYMMDD-HHMMSS.N.jsonl)
3. JVM Crash Logs¶
Location: ./log/hs_err_pid*.log (default)
Customize BEFORE the JVM starts:
import os
# Set custom crash log location
os.environ["ARCADEDB_JVM_ERROR_FILE"] = "/var/log/arcade/errors.log"
# Now import and use
import arcadedb_embedded as arcadedb
server = arcadedb.create_server(root_password="password123")
# Crash logs will go to /var/log/arcade/errors.log
Important: Must be set before the first server or database is created.
Complete Examples¶
Basic Server with Studio¶
import arcadedb_embedded as arcadedb
# Create and start server
server = arcadedb.create_server(
root_path="./databases",
root_password="admin123"
)
server.start()
print(f"Studio available at: {server.get_studio_url()}")
print("Press Ctrl+C to stop...")
try:
# Keep server running
import time
while True:
time.sleep(1)
except KeyboardInterrupt:
print("\nStopping server...")
server.stop()
Usage:
- Run the script
- Open browser to
http://localhost:2480/ - Login with username
rootand passwordadmin123 - Create and query databases via Studio UI
Web Application Pattern¶
import arcadedb_embedded as arcadedb
from flask import Flask, jsonify
app = Flask(__name__)
# Create and start the server once, at import time
# (production mode: no Studio page is served)
server = arcadedb.create_server(
root_path="./app_databases",
root_password="secure_password",
config={"http_port": 2480, "mode": "production"}
)
server.start()
# create_database() returns the existing database when there is one
db = server.create_database("app_db")
try:
if not db.schema.exists_type("User"):
db.command("sql", "CREATE DOCUMENT TYPE User")
db.command("sql", "CREATE PROPERTY User.email STRING")
db.command("sql", "CREATE INDEX ON User (email) UNIQUE_HASH")
finally:
db.close()
@app.route("/users")
def get_users():
"""Get all users via ArcadeDB Python API."""
db = server.get_database("app_db")
try:
result_set = db.query("sql", "SELECT * FROM User")
users = [result.to_dict() for result in result_set]
return jsonify(users)
finally:
db.close()
if __name__ == "__main__":
try:
app.run(host="0.0.0.0", port=5000)
finally:
server.stop()
Multi-Database Server¶
import arcadedb_embedded as arcadedb
# Context manager for automatic cleanup
with arcadedb.create_server(root_password="password123") as server:
# Create multiple databases
users_db = server.create_database("users")
products_db = server.create_database("products")
analytics_db = server.create_database("analytics")
# Initialize schemas
users_db.command("sql", "CREATE VERTEX TYPE User")
users_db.command("sql", "CREATE PROPERTY User.email STRING")
products_db.command("sql", "CREATE DOCUMENT TYPE Product")
products_db.command("sql", "CREATE PROPERTY Product.sku STRING")
# Use databases
with users_db.transaction():
users_db.command("sql", "INSERT INTO User SET email = ?", "alice@example.com")
with products_db.transaction():
products_db.command("sql", "INSERT INTO Product SET sku = ?", "PROD-001")
# Query different databases
print("Users:")
result = users_db.query("sql", "SELECT FROM User")
for r in result:
print(f" {r.get('email')}")
print("Products:")
result = products_db.query("sql", "SELECT FROM Product")
for r in result:
print(f" {r.get('sku')}")
# Close databases
users_db.close()
products_db.close()
analytics_db.close()
# Server automatically stopped
print("All databases shut down cleanly")
Development Server with Auto-Reload¶
import arcadedb_embedded as arcadedb
import time
import signal
import sys
# Global server instance
server = None
def shutdown_handler(signum, frame):
"""Handle Ctrl+C gracefully."""
print("\nShutting down server...")
if server:
server.stop()
sys.exit(0)
# Register signal handler
signal.signal(signal.SIGINT, shutdown_handler)
# Start server
server = arcadedb.create_server(
root_path="./dev_databases",
root_password="dev_password",
config={
"http_port": 2480,
"mode": "development"
}
)
server.start()
# Create/open dev database
try:
db = server.get_database("dev")
except:
db = server.create_database("dev")
print("Created new dev database")
# Initialize schema
db.command("sql", "CREATE VERTEX TYPE TestNode")
db.command("sql", "CREATE EDGE TYPE TestEdge")
db.close()
print(f"\n{'=' * 60}")
print(f"Development Server Running")
print(f"{'=' * 60}")
print(f"Studio UI: {server.get_studio_url()}")
print(f"HTTP API: http://localhost:{server.get_http_port()}/api/v1/")
print(f"Database: 'dev' (password: 'dev_password')")
print(f"\nPress Ctrl+C to stop")
print(f"{'=' * 60}\n")
# Keep running
while True:
time.sleep(1)
Production Deployment¶
import arcadedb_embedded as arcadedb
import os
import logging
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Production configuration
ROOT_PASSWORD = os.environ.get("ARCADEDB_ROOT_PASSWORD", "changeme")
ROOT_PATH = os.environ.get("ARCADEDB_ROOT_PATH", "/var/lib/arcadedb")
HTTP_PORT = int(os.environ.get("ARCADEDB_HTTP_PORT", "2480"))
if ROOT_PASSWORD == "changeme":
logger.warning("Using default password - INSECURE for production!")
# Create production server
server = arcadedb.create_server(
root_path=ROOT_PATH,
root_password=ROOT_PASSWORD,
config={
"http_port": HTTP_PORT,
"host": "0.0.0.0",
"mode": "production",
"server_httpSessionExpireTimeout": 30 # seconds
}
)
try:
server.start()
logger.info(f"Production server started on port {HTTP_PORT}")
logger.info(f"Database path: {ROOT_PATH}")
# Keep running
import time
while True:
time.sleep(60)
logger.debug("Server heartbeat - still running")
except KeyboardInterrupt:
logger.info("Shutdown signal received")
except Exception as e:
logger.error(f"Server error: {e}")
finally:
server.stop()
logger.info("Server stopped")
Deployment:
# Set environment variables
export ARCADEDB_ROOT_PASSWORD="super_secure_password_123"
export ARCADEDB_ROOT_PATH="/data/arcadedb"
export ARCADEDB_HTTP_PORT="8080"
# Run server
python production_server.py
HTTP REST API¶
Once the server is running, you can access databases via HTTP:
Query via HTTP¶
# POST query
curl -X POST http://localhost:2480/api/v1/query/mydb \
-u root:password \
-H "Content-Type: application/json" \
-d '{
"language": "sql",
"command": "SELECT FROM Person WHERE age > 25"
}'
# GET simple query
curl "http://localhost:2480/api/v1/query/mydb/sql/SELECT%20*%20FROM%20Person" \
-u root:password
Create Record via HTTP¶
curl -X POST http://localhost:2480/api/v1/command/mydb \
-u root:password \
-H "Content-Type: application/json" \
-d '{
"language": "sql",
"command": "INSERT INTO Person SET name = '\''Alice'\'', age = 30"
}'
Server HTTP commands are auto-transactional per request. For multiple writes that must succeed together, use explicit HTTP transactional endpoints or send a single multi-statement SQLScript transaction.
Error Handling¶
from arcadedb_embedded import ArcadeDBError
try:
server = arcadedb.create_server(root_password="password123")
server.start()
# May fail if database doesn't exist
db = server.get_database("nonexistent")
except ArcadeDBError as e:
print(f"Error: {e}")
finally:
if server.is_started():
server.stop()
Common Errors:
- Port already in use: Another process using port 2480
- Solution: Change
http_portin config or stop conflicting process
- Solution: Change
- Permission denied: Cannot write to
root_path- Solution: Check directory permissions
- Database not found:
get_database()on non-existent DB- Solution: Use
create_database()first
- Solution: Use
See Also¶
- Server Mode Guide - Comprehensive server usage guide
- Database API - Database operations
- Getting Started - Quick start tutorial