Skip to content

Developer Manual

David H. edited this page Apr 1, 2025 · 3 revisions

LitePolis Database Example Developer Manual

This manual provides instructions for developers looking to import and utilize the LitePolis database example code in their projects. The central interface for interacting with the database is the DatabaseActor class.

Introduction

This repository, LitePolis-database-example, provides an example of how to structure and interact with a database for a fictional city-building game called LitePolis. It includes data models for users, conversations, and comments, implemented using SQLModel. The DatabaseActor class aggregates the functionalities for interacting with these models.

Python 3.x: This library is written in Python.

Installation

You can install the litepolis-database-example library using pip:

pip install litepolis-database-example

Configuration

The database connection URL for the litepolis-database-example library is configured via the litepolis configuration system or defaults to an SQLite database.

Default Configuration

By default, the library uses an SQLite database file named database.db in the current directory:

# Default configuration (from utils.py)
DEFAULT_CONFIG = {
    "sqlite_url": "sqlite:///database.db"
}

Production Configuration

In a production environment, it's recommended to configure the database URL using the litepolis configuration system. This typically involves a configuration file (e.g., ~/.litepolis/config.conf as mentioned in the original manual, although the exact mechanism depends on the litepolis.get_config implementation). The utils.py file attempts to load sqlite_url via get_config when not running under Pytest.

Example config.conf structure:

[default] # Or appropriate section depending on get_config
sqlite_url = your_production_database_url # e.g., postgresql://user:password@host:port/database

Testing Configuration

For testing, you can let the library use the default SQLite URL, or potentially override environment variables if your test setup modifies how litepolis.get_config works. Directly modifying DEFAULT_CONFIG in utils.py as suggested previously is generally not recommended for testing.

Usage

This section demonstrates how to import and use the DatabaseActor class and its methods for interacting with users, conversations, and comments.

Importing the DatabaseActor Class

After installing the library, you can import the DatabaseActor class and the data models:

from litepolis_database_example import DatabaseActor, User, Conversation, Comment

Interacting with Users

The DatabaseActor inherits methods from UserManager to interact with user data.

# Example usage:

# Create a new user (returns a User object)
new_user = DatabaseActor.create_user(email="[email protected]", password="securepassword123")
print(f"Created user: ID={new_user.id}, Email={new_user.email}") # Access attributes directly

# Get a user by ID (returns a User object or None)
user_id_to_get = new_user.id
user = DatabaseActor.read_user(user_id_to_get)
if user:
    print(f"Retrieved user by ID {user_id_to_get}: {user}")
    print(f"Username (Email): {user.email}") # Access attributes
else:
    print(f"User with ID {user_id_to_get} not found.")

# Get all users (returns a List[User])
all_users = DatabaseActor.read_users()
print(f"All Users ({len(all_users)}):")
for u in all_users:
    print(f"  - ID: {u.id}, Email: {u.email}, Privilege: {u.privilege}")

# Update a user's details (returns updated User object or None)
updated_user = DatabaseActor.update_user(
    user_id=new_user.id,
    email="[email protected]",
    password="newsecurepassword456",
    privilege="admin"
)
if updated_user:
    print(f"Updated user: {updated_user}")
else:
    print(f"Failed to update user with ID {new_user.id}.")


# Delete a user (returns True if successful, False otherwise)
deleted = DatabaseActor.delete_user(new_user.id)
if deleted:
    print(f"Successfully deleted user with ID {new_user.id}")
else:
    print(f"Failed to delete user with ID {new_user.id} (maybe already deleted).")

User Model (Users.py): Defines the structure: id, email, password, privilege.

Interacting with Conversations

The DatabaseActor inherits methods from ConversationManager.

# Example usage (assuming a user exists with ID=1):
creator_user_id = 1 # Replace with a valid user ID from your DB

# Create a new conversation (returns a Conversation object)
new_convo = DatabaseActor.create_conversation(
    title="Project Alpha Kickoff",
    description="Initial planning meeting notes.",
    creator_id=creator_user_id
)
print(f"Created conversation: ID={new_convo.id}, Title={new_convo.title}")

# Get a conversation by ID (returns Conversation object or None)
convo_id_to_get = new_convo.id
conversation = DatabaseActor.read_conversation(convo_id_to_get)
if conversation:
    print(f"Retrieved conversation by ID {convo_id_to_get}: {conversation}")
    print(f"Conversation Title: {conversation.title}")
else:
    print(f"Conversation with ID {convo_id_to_get} not found.")

# Get all conversations (returns List[Conversation])
all_conversations = DatabaseActor.read_conversations()
print(f"All Conversations ({len(all_conversations)}):")
for c in all_conversations:
    print(f"  - ID: {c.id}, Title: {c.title}, Creator ID: {c.creator_id}")


# Update a conversation (returns updated Conversation or None)
updated_convo = DatabaseActor.update_conversation(
    conversation_id=new_convo.id,
    title="Project Alpha - Updated Plan",
    description="Revised planning notes.",
    creator_id=creator_user_id # Creator ID might be updatable based on the code
)
if updated_convo:
    print(f"Updated conversation: {updated_convo}")
else:
    print(f"Failed to update conversation ID {new_convo.id}.")


# Delete a conversation (returns True if successful, False otherwise)
deleted_convo = DatabaseActor.delete_conversation(new_convo.id)
if deleted_convo:
    print(f"Successfully deleted conversation with ID {new_convo.id}")
else:
    print(f"Failed to delete conversation ID {new_convo.id}.")

Conversation Model (Conversations.py): Defines the structure: id, title, description, creator_id.

Interacting with Comments

The DatabaseActor inherits methods from CommentManager.

# Example usage (assuming conversation_id and user_id exist):
# First, ensure a user and conversation exist. We'll reuse IDs from previous examples if run sequentially.
# Or create them if needed:
# temp_user = DatabaseActor.create_user(email="[email protected]", password="pw")
# temp_convo = DatabaseActor.create_conversation(title="Temp Convo", description="Desc", creator_id=temp_user.id)
# existing_conversation_id = temp_convo.id
# existing_user_id = temp_user.id
existing_conversation_id = 1 # Replace with a valid conversation ID
existing_user_id = 1       # Replace with a valid user ID

# Create a comment (returns Comment object)
new_comment = DatabaseActor.create_comment(
    conversation_id=existing_conversation_id,
    user_id=existing_user_id,
    comment_text="This is the first comment on this topic.",
    # moderated and approved default to False
)
print(f"Added comment: ID={new_comment.id}, Text={new_comment.comment}")


# Get a specific comment by ID (returns Comment object or None)
comment_id_to_get = new_comment.id
comment = DatabaseActor.read_comment(comment_id_to_get)
if comment:
    print(f"Retrieved comment by ID {comment_id_to_get}: {comment}")
    print(f"Comment Text: {comment.comment}") # Access attributes
    print(f"Approved status: {comment.approved}")
else:
    print(f"Comment with ID {comment_id_to_get} not found.")

# Get all comments (returns List[Comment])
# Note: This gets ALL comments, not just for one conversation.
# You might want a specific method like 'get_comments_for_conversation' if needed (it's not in the current code).
all_comments = DatabaseActor.read_comments()
print(f"All Comments ({len(all_comments)}):")
for cm in all_comments:
    print(f"  - ID: {cm.id}, ConvoID: {cm.conversation_id}, UserID: {cm.user_id}, Approved: {cm.approved}, Text: {cm.comment[:30]}...")


# Update a comment (returns updated Comment or None)
updated_comment = DatabaseActor.update_comment(
    comment_id=new_comment.id,
    comment_text="This comment has been reviewed and updated.",
    moderated=True,
    approved=True
)
if updated_comment:
    print(f"Updated comment: {updated_comment}")
else:
    print(f"Failed to update comment ID {new_comment.id}.")


# Delete a comment (returns True if successful, False otherwise)
deleted_comment = DatabaseActor.delete_comment(new_comment.id)
if deleted_comment:
    print(f"Successfully deleted comment with ID {new_comment.id}")
else:
    print(f"Failed to delete comment ID {new_comment.id}.")

Comment Model (Comments.py): Defines the structure: id, comment (text), user_id, conversation_id, moderated, approved.