diff --git a/README.md b/README.md index 0e36679..33a8fe1 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Environment variables: - `ARANGO_USERNAME` - `ARANGO_PWD` -Tthe package will use `env_manager` to set them automatically (first time you may need to provide a password). +The package will use `env_manager` to set them automatically (first time you may need to provide a password). Example: @@ -35,6 +35,30 @@ from _arango import arango results = arango.execute_aql("FOR doc IN my_collection RETURN doc") ``` +## AdminArango: Database and User Administration + +The `AdminArango` class provides administrative functionality for ArangoDB, such as creating and deleting databases, managing users, and setting permissions. It connects to the `_system` database for these operations. + +Example usage: + +```python +from _arango.arango import AdminArango + +admin = AdminArango() +admin.create_database("mydb") +admin.create_user("username", password="secret") +admin.set_user_permission("username", "rw", "mydb") +admin.list_databases() +admin.delete_user("username") +admin.delete_database("mydb") +``` + +Features: +- Create and delete databases +- List all databases +- Create and delete users +- Set user permissions for databases and collections + ## Using as a Base for Your Own Project If you want to use this package as a starting point for your own ArangoDB utilities, you can clone the repository: diff --git a/arango.py b/arango.py index 42935d8..d866ed2 100644 --- a/arango.py +++ b/arango.py @@ -1,13 +1,15 @@ -from arango import ArangoClient -from dotenv import load_dotenv import os import re -from typing import Optional +from typing import Any, Dict, Optional + +from arango import ArangoClient +from dotenv import load_dotenv load_dotenv() -if 'ARANGO_HOST' not in os.environ: +if "ARANGO_HOST" not in os.environ: import env_manager + env_manager.set_env() @@ -20,6 +22,10 @@ class Arango: - ARANGO_DB: The name of the database to connect to. - ARANGO_USERNAME: Username for authentication. - ARANGO_PWD: Password for authentication. + + Example usage: + arango = Arango() + results = arango.execute_aql("FOR doc IN my_collection RETURN doc") """ def __init__(self): @@ -60,7 +66,12 @@ class Arango: col.truncate() print(f"Truncated collection: {db['name']}") - def execute_aql(self, query: str, bind_vars: Optional[dict] = None, batch_size: Optional[int] = None) -> list[dict]: + def execute_aql( + self, + query: str, + bind_vars: Optional[dict] = None, + batch_size: Optional[int] = None, + ) -> list[dict]: """ Executes an AQL (Arango Query Language) query and returns the results as a list of dictionaries. @@ -72,9 +83,152 @@ class Arango: Returns: list[dict]: The query results. """ - cursor = self.db.aql.execute(query, bind_vars=bind_vars or {}, batch_size=batch_size) + cursor = self.db.aql.execute( + query, bind_vars=bind_vars or {}, batch_size=batch_size + ) return list(cursor) + def create_collection(self, name: str): + """ + Creates a new collection in the database if it does not already exist. + + Args: + name (str): The name of the collection to create. + """ + if not self.db.has_collection(name): + self.db.create_collection(name) + print(f"Created collection: {name}") + else: + print(f"Collection '{name}' already exists.") + + +load_dotenv() + + +class AdminArango: + """ + Provides administrative functionalities for ArangoDB, such as managing databases and users. + Connects to the '_system' database for admin operations. + + Example usage: + admin = AdminArango() + admin.create_database("mydb") + admin.create_user("username", password="secret") + admin.set_user_permission("username", "rw", "mydb") + """ + + def __init__(self): + """ + Initializes the AdminArango client and connects to the '_system' database using environment variables. + """ + self.client = ArangoClient(hosts=os.environ.get("ARANGO_HOST")) + self.sys_db = self.client.db( + "_system", + username=os.environ.get("ARANGO_USERNAME"), + password=os.environ.get("ARANGO_PWD"), + ) + + # --- Database Management --- + + def create_database( + self, db_name: str, users: Optional[list[Dict[str, Any]]] = None + ): + """ + Creates a new database in ArangoDB. + + Args: + db_name (str): Name of the database to create. + users (Optional[list[dict]]): List of user dicts to create with the database. + """ + if not self.sys_db.has_database(db_name): + self.sys_db.create_database(db_name, users=users) + print(f"Created database: {db_name}") + else: + print(f"Database '{db_name}' already exists.") + + def delete_database(self, db_name: str): + """ + Deletes a database from ArangoDB. + + Args: + db_name (str): Name of the database to delete. + """ + if self.sys_db.has_database(db_name): + self.sys_db.delete_database(db_name) + print(f"Deleted database: {db_name}") + else: + print(f"Database '{db_name}' does not exist.") + + def list_databases(self): + """ + Lists all databases in the ArangoDB server. + + Returns: + list[str]: List of database names. + """ + return self.sys_db.databases() + + # --- User Management --- + + def create_user( + self, + username: str, + password: Optional[str] = None, + active: Optional[bool] = True, + extra: Optional[dict] = None, + ): + """ + Creates a new user in ArangoDB. + + Args: + username (str): Username for the new user. + password (Optional[str]): Password for the user. + active (Optional[bool]): Whether the user is active. + extra (Optional[dict]): Extra user attributes. + """ + if not self.sys_db.has_user(username): + self.sys_db.create_user( + username, password=password, active=active, extra=extra + ) + print(f"Created user: {username}") + else: + print(f"User '{username}' already exists.") + + def delete_user(self, username: str): + """ + Deletes a user from ArangoDB. + + Args: + username (str): Username of the user to delete. + """ + if self.sys_db.has_user(username): + self.sys_db.delete_user(username) + print(f"Deleted user: {username}") + else: + print(f"User '{username}' does not exist.") + + + def set_user_permission( + self, + username: str, + permission: str, + database: str, + collection: Optional[str] = None, + ): + """ + Sets user permissions for a database or collection. + + Args: + username (str): Username to set permissions for. + permission (str): "rw" (read/write), "ro" (read-only), "none" (no access). + database (str): Database name. + collection (Optional[str]): Collection name (optional). + """ + self.sys_db.update_permission(username, permission, database, collection) + print( + f"Set permission '{permission}' for user '{username}' on database '{database}'" + + (f", collection '{collection}'" if collection else "") + ) arango = Arango()