import requests
import json
import uuid
from datetime import datetime
from typing import Dict, Any, List
class FortressClient:
def __init__(self, base_url: str = "http://localhost:8080", api_key: str = None):
self.base_url = base_url.rstrip('/')
self.api_key = api_key
self.session = requests.Session()
if api_key:
self.session.headers.update({"X-API-Key": api_key})
def _request(self, method: str, endpoint: str, **kwargs) -> Dict[str, Any]:
url = f"{self.base_url}{endpoint}"
response = self.session.request(method, url, **kwargs)
response.raise_for_status()
return response.json()
def create_database(self, name: str, algorithm: str = "aegis256",
key_rotation_interval: str = "23h",
storage_path: str = "./data") -> Dict[str, Any]:
data = {
"name": name,
"algorithm": algorithm,
"key_rotation_interval": key_rotation_interval,
"storage_path": storage_path
}
return self._request("POST", "/api/v1/databases", json=data)
def list_databases(self) -> Dict[str, Any]:
return self._request("GET", "/api/v1/databases")
def get_database(self, name: str) -> Dict[str, Any]:
return self._request("GET", f"/api/v1/databases/{name}")
def delete_database(self, name: str) -> Dict[str, Any]:
return self._request("DELETE", f"/api/v1/databases/{name}")
def create_table(self, database: str, table_name: str, columns: List[Dict[str, Any]],
encryption: str = "balanced") -> Dict[str, Any]:
data = {
"name": table_name,
"columns": columns,
"encryption": encryption
}
return self._request("POST", f"/api/v1/databases/{database}/tables", json=data)
def list_tables(self, database: str) -> Dict[str, Any]:
return self._request("GET", f"/api/v1/databases/{database}/tables")
def get_table_schema(self, database: str, table: str) -> Dict[str, Any]:
return self._request("GET", f"/api/v1/databases/{database}/tables/{table}/schema")
def drop_table(self, database: str, table: str) -> Dict[str, Any]:
return self._request("DELETE", f"/api/v1/databases/{database}/tables/{table}")
def insert_data(self, database: str, table: str, data: Dict[str, Any]) -> Dict[str, Any]:
return self._request("POST", f"/api/v1/databases/{database}/tables/{table}/data", json=data)
def query_data(self, database: str, table: str, params: Dict[str, Any] = None) -> Dict[str, Any]:
return self._request("GET", f"/api/v1/databases/{database}/tables/{table}/data", params=params or {})
def bulk_insert(self, database: str, table: str, data: List[Dict[str, Any]]) -> Dict[str, Any]:
return self._request("POST", f"/api/v1/databases/{database}/tables/{table}/bulk", json={"data": data})
def update_data(self, database: str, table: str, record_id: str, data: Dict[str, Any]) -> Dict[str, Any]:
return self._request("PUT", f"/api/v1/databases/{database}/tables/{table}/data/{record_id}", json=data)
def delete_data(self, database: str, table: str, record_id: str) -> Dict[str, Any]:
return self._request("DELETE", f"/api/v1/databases/{database}/tables/{table}/data/{record_id}")
def execute_query(self, database: str, sql: str, parameters: List[Any] = None) -> Dict[str, Any]:
data = {
"sql": sql,
"parameters": parameters or []
}
return self._request("POST", f"/api/v1/databases/{database}/query", json=data)
def rotate_keys(self, database: str, table: str) -> Dict[str, Any]:
return self._request("POST", f"/api/v1/databases/{database}/tables/{table}/rotate-keys")
def rotate_keys_zero_downtime(self, database: str, table: str) -> Dict[str, Any]:
return self._request("POST", f"/api/v1/databases/{database}/tables/{table}/rotate-keys-zero-downtime")
def get_rotation_status(self, database: str, table: str) -> Dict[str, Any]:
return self._request("GET", f"/api/v1/databases/{database}/tables/{table}/rotation-status")
def get_encryption_metadata(self, database: str, table: str) -> Dict[str, Any]:
return self._request("GET", f"/api/v1/databases/{database}/tables/{table}/encryption-metadata")
def health_check(self) -> Dict[str, Any]:
return self._request("GET", "/health")
def get_metrics(self) -> Dict[str, Any]:
return self._request("GET", "/metrics")
def main():
client = FortressClient("http://localhost:8080")
print("๐ Fortress API Example")
print("=" * 50)
try:
print("\n๐ Checking API health...")
health = client.health_check()
print(f"โ
API Status: Healthy")
print("\n๐๏ธ Creating database...")
db_name = f"example_db_{uuid.uuid4().hex[:8]}"
db_response = client.create_database(
name=db_name,
algorithm="aegis256",
key_rotation_interval="23h",
storage_path=f"./data/{db_name}"
)
print(f"โ
Database created: {db_name}")
print("\n๐ Creating users table...")
table_columns = [
{"name": "id", "type": "uuid", "primary_key": True, "nullable": False},
{"name": "name", "type": "text", "nullable": False},
{"name": "email", "type": "text", "nullable": False},
{"name": "password", "type": "encrypted", "nullable": False, "encryption": "fortress"},
{"name": "created_at", "type": "timestamp", "nullable": False}
]
table_response = client.create_table(db_name, "users", table_columns, "balanced")
print(f"โ
Table created: users")
print("\n๐ Inserting sample users...")
users = [
{
"id": str(uuid.uuid4()),
"name": "Alice Johnson",
"email": "alice@example.com",
"password": "super_secret_password_123",
"created_at": datetime.utcnow().isoformat()
},
{
"id": str(uuid.uuid4()),
"name": "Bob Smith",
"email": "bob@example.com",
"password": "another_secure_password_456",
"created_at": datetime.utcnow().isoformat()
},
{
"id": str(uuid.uuid4()),
"name": "Charlie Brown",
"email": "charlie@example.com",
"password": "yet_another_password_789",
"created_at": datetime.utcnow().isoformat()
}
]
for user in users:
response = client.insert_data(db_name, "users", user)
print(f"โ
Inserted user: {user['name']}")
print("\n๐ Querying all users...")
query_response = client.query_data(db_name, "users")
print(f"โ
Found {query_response['data']['total_count']} users")
print("\n๐ Executing SQL query...")
sql_response = client.execute_query(
db_name,
"SELECT name, email FROM users WHERE name LIKE ?",
["Alice%"]
)
print(f"โ
SQL query returned {sql_response['data']['total_count']} results")
print("\n๐ Getting encryption metadata...")
encryption_meta = client.get_encryption_metadata(db_name, "users")
print(f"โ
Table encryption: {encryption_meta['data']['table_encryption']}")
print(f"โ
Zero-downtime rotation: {encryption_meta['data']['zero_downtime_enabled']}")
print("\nโ๏ธ Updating a user...")
if users:
user_id = users[0]["id"]
update_data = {"email": "alice.updated@example.com"}
update_response = client.update_data(db_name, "users", user_id, update_data)
print(f"โ
Updated user email")
print("\n๐ Listing tables...")
tables_response = client.list_tables(db_name)
print(f"โ
Database has {tables_response['data']['total_count']} tables")
print("\n๐ Getting table schema...")
schema_response = client.get_table_schema(db_name, "users")
columns = schema_response['data']['columns']
print(f"โ
Users table has {len(columns)} columns")
print("\n๐งน Cleaning up...")
client.drop_table(db_name, "users")
print("โ
Dropped users table")
client.delete_database(db_name)
print(f"โ
Deleted database: {db_name}")
print("\n๐ Example completed successfully!")
except requests.exceptions.ConnectionError:
print("โ Error: Could not connect to Fortress API server")
print("๐ก Make sure the server is running on http://localhost:8080")
print("๐ก You can start it with: cargo run --bin fortress-server")
except requests.exceptions.HTTPError as e:
print(f"โ HTTP Error: {e}")
try:
error_data = e.response.json()
print(f" Details: {error_data}")
except:
pass
except Exception as e:
print(f"โ Error: {e}")
if __name__ == "__main__":
main()