8.9 KiB
Appwrite Setup Guide
This guide walks you through setting up Appwrite for Code of Conquest.
Prerequisites
- Appwrite Cloud account (https://cloud.appwrite.io) OR self-hosted Appwrite instance
- Admin access to create projects and collections
Step 1: Create Project
- Log in to Appwrite Console
- Click "Create Project"
- Project Name:
Code of Conquest - Project ID: (auto-generated, save this for
.env) - Click "Create"
Step 2: Get API Credentials
- In your project, go to Settings
- Copy the following values:
- Project ID →
.envasAPPWRITE_PROJECT_ID - API Endpoint →
.envasAPPWRITE_ENDPOINT(usuallyhttps://cloud.appwrite.io/v1)
- Project ID →
- Go to Settings → API Keys
- Click "Create API Key"
- Name:
Backend Server - Expiration: Never (or long-term)
- Scopes: Select ALL scopes (for development)
- Name:
- Copy the generated API key →
.envasAPPWRITE_API_KEY
Step 3: Create Database
- Go to Databases in the left sidebar
- Click "Create Database"
- Database ID:
main - Name:
Main Database - Click "Create"
Step 4: Create Collections
Create the following collections in the main database.
Collection 1: characters
| Setting | Value |
|---|---|
| Collection ID | characters |
| Collection Name | Characters |
Attributes:
| Key | Type | Size | Required | Default | Array |
|---|---|---|---|---|---|
userId |
String | 255 | Yes | - | No |
characterData |
String | 100000 | Yes | - | No |
created_at |
DateTime | - | Yes | - | No |
updated_at |
DateTime | - | Yes | - | No |
is_active |
Boolean | - | Yes | true | No |
Indexes:
| Key | Type | Attributes |
|---|---|---|
userId_index |
Key | userId (ASC) |
active_index |
Key | is_active (ASC) |
Permissions:
- Create:
users - Read:
users - Update:
users - Delete:
users
Collection 2: game_sessions
| Setting | Value |
|---|---|
| Collection ID | game_sessions |
| Collection Name | Game Sessions |
Attributes:
| Key | Type | Size | Required | Default | Array |
|---|---|---|---|---|---|
party_member_ids |
String | 255 | Yes | - | Yes |
config |
String | 5000 | Yes | - | No |
combat_encounter |
String | 50000 | No | - | No |
conversation_history |
String | 500000 | Yes | - | No |
game_state |
String | 50000 | Yes | - | No |
turn_order |
String | 255 | Yes | - | Yes |
current_turn |
Integer | - | Yes | 0 | No |
turn_number |
Integer | - | Yes | 1 | No |
created_at |
DateTime | - | Yes | - | No |
last_activity |
DateTime | - | Yes | - | No |
status |
String | 50 | Yes | active | No |
Indexes:
| Key | Type | Attributes |
|---|---|---|
status_index |
Key | status (ASC) |
last_activity_index |
Key | last_activity (DESC) |
Permissions:
- Create:
users - Read:
users - Update:
users - Delete:
users
Collection 3: marketplace_listings
| Setting | Value |
|---|---|
| Collection ID | marketplace_listings |
| Collection Name | Marketplace Listings |
Attributes:
| Key | Type | Size | Required | Default | Array |
|---|---|---|---|---|---|
seller_id |
String | 255 | Yes | - | No |
character_id |
String | 255 | Yes | - | No |
item_data |
String | 10000 | Yes | - | No |
listing_type |
String | 50 | Yes | - | No |
price |
Integer | - | No | - | No |
starting_bid |
Integer | - | No | - | No |
current_bid |
Integer | - | No | - | No |
buyout_price |
Integer | - | No | - | No |
bids |
String | 50000 | No | - | No |
auction_end |
DateTime | - | No | - | No |
status |
String | 50 | Yes | active | No |
created_at |
DateTime | - | Yes | - | No |
Indexes:
| Key | Type | Attributes |
|---|---|---|
listing_type_index |
Key | listing_type (ASC) |
status_index |
Key | status (ASC) |
seller_index |
Key | seller_id (ASC) |
auction_end_index |
Key | auction_end (ASC) |
Permissions:
- Create:
users - Read:
any(public can browse) - Update:
users(owner only, enforced in code) - Delete:
users(owner only, enforced in code)
Collection 4: transactions
| Setting | Value |
|---|---|
| Collection ID | transactions |
| Collection Name | Transactions |
Attributes:
| Key | Type | Size | Required | Default | Array |
|---|---|---|---|---|---|
buyer_id |
String | 255 | Yes | - | No |
seller_id |
String | 255 | Yes | - | No |
listing_id |
String | 255 | No | - | No |
item_data |
String | 10000 | Yes | - | No |
price |
Integer | - | Yes | - | No |
timestamp |
DateTime | - | Yes | - | No |
transaction_type |
String | 50 | Yes | - | No |
Indexes:
| Key | Type | Attributes |
|---|---|---|
buyer_index |
Key | buyer_id (ASC) |
seller_index |
Key | seller_id (ASC) |
timestamp_index |
Key | timestamp (DESC) |
Permissions:
- Create: System only (API key)
- Read:
users(buyer/seller only, enforced in code) - Update: None
- Delete: None
Step 5: Enable Realtime
- Go to Settings → Realtime
- Enable Realtime API
- Add allowed origins:
http://localhost:5000(development)- Your production domain (when ready)
Step 6: Configure Authentication
- Go to Auth in the left sidebar
- Enable Email/Password authentication
- Configure password requirements:
- Minimum length: 8
- Require lowercase: Yes
- Require uppercase: Yes
- Require numbers: Yes
- Require special characters: Optional
Optional: Enable OAuth providers if desired (Google, GitHub, etc.)
Step 7: Update .env File
Copy .env.example to .env and fill in the values:
cp .env.example .env
Update the following in .env:
APPWRITE_ENDPOINT=https://cloud.appwrite.io/v1
APPWRITE_PROJECT_ID=your-project-id-here
APPWRITE_API_KEY=your-api-key-here
APPWRITE_DATABASE_ID=main
Step 8: Test Connection
Create a test script to verify Appwrite connection:
test_appwrite.py:
from appwrite.client import Client
from appwrite.services.databases import Databases
from dotenv import load_dotenv
import os
load_dotenv()
# Initialize Appwrite client
client = Client()
client.set_endpoint(os.getenv('APPWRITE_ENDPOINT'))
client.set_project(os.getenv('APPWRITE_PROJECT_ID'))
client.set_key(os.getenv('APPWRITE_API_KEY'))
# Test database connection
databases = Databases(client)
try:
# List collections
result = databases.list_collections(
database_id=os.getenv('APPWRITE_DATABASE_ID')
)
print(f"✓ Connected to Appwrite successfully!")
print(f"✓ Found {result['total']} collections:")
for collection in result['collections']:
print(f" - {collection['name']} (ID: {collection['$id']})")
except Exception as e:
print(f"✗ Failed to connect to Appwrite:")
print(f" Error: {str(e)}")
Run:
source venv/bin/activate
pip install appwrite python-dotenv
python test_appwrite.py
Security Best Practices
Production Permissions
For production, tighten permissions:
-
characters collection:
- Users can only access their own characters (enforce in code)
- Add server-side checks for
userIdmatch
-
game_sessions collection:
- Party members can read (enforce in code)
- Active player can write (enforce in code)
-
marketplace_listings collection:
- Anyone can read (browsing)
- Only owner can update/delete (enforce in code)
-
transactions collection:
- Create via API key only
- Users can read only their own transactions (enforce in code)
API Key Security
- Never commit
.envfile to git - Use different API keys for dev/staging/production
- Rotate API keys periodically
- Use minimal scopes in production (not "all")
Troubleshooting
Common Issues
Issue: "Project not found"
- Solution: Verify
APPWRITE_PROJECT_IDmatches the project ID in Appwrite Console
Issue: "Invalid API key"
- Solution: Regenerate API key and update
.env
Issue: "Collection not found"
- Solution: Verify collection IDs match exactly (case-sensitive)
Issue: "Permission denied"
- Solution: Check collection permissions in Appwrite Console
Issue: "Realtime not working"
- Solution: Verify Realtime is enabled and origins are configured
Next Steps
After completing Appwrite setup:
- ✅ Install dependencies:
pip install -r requirements.txt - ✅ Test connection with
test_appwrite.py - ✅ Create Appwrite service wrapper (
app/services/appwrite_service.py) - Start building API endpoints (Phase 2)
Resources
- Appwrite Documentation: https://appwrite.io/docs
- Appwrite Python SDK: https://github.com/appwrite/sdk-for-python
- Appwrite Console: https://cloud.appwrite.io
- Appwrite Discord: https://appwrite.io/discord