Skip to main content
User-based resource management allows you to associate Acontext resources (Spaces, Sessions, Disks, and Skills) with user identifiers. This enables multi-tenant scenarios, per-user resource isolation, and simplified resource cleanup.

What you’ll learn

In this guide, you’ll learn how to:
  • Associate resources (Spaces, Sessions, Disks, Skills) with user identifiers
  • Filter resources by user
  • Delete a user and cascade delete all associated resources
  • Build multi-tenant applications with per-user resource isolation

Prerequisites

Before you begin, ensure you have:

Initialize the client

First, create a client instance with your API key and base URL.
import os
from acontext import AcontextClient

client = AcontextClient(
    api_key=os.getenv("ACONTEXT_API_KEY"),
)

# If you're using self-hosted Acontext:
# client = AcontextClient(
#     base_url="http://localhost:8029/api/v1",
#     api_key="sk-ac-your-root-api-bearer-token",
# )

client.ping()
Never hardcode API keys in production code. Use environment variables instead.

Step-by-step tutorial

1

Create resources with user association

Associate resources with a user by passing the user parameter when creating them. User records are created automatically when first referenced.
# Create a space for a user
space = client.spaces.create(
    user="[email protected]",
    configs={"name": "Alice's Workspace"}
)
print(f"Created space: {space.id}")

# Create a session for the same user
session = client.sessions.create(
    user="[email protected]",
    space_id=space.id,
    configs={"mode": "chat"}
)
print(f"Created session: {session.id}")

# Create a disk for the user
disk = client.disks.create(user="[email protected]")
print(f"Created disk: {disk.id}")
The user parameter is optional. Resources created without a user parameter are not associated with any user and can still be queried and managed normally.
2

Filter resources by user

All list operations support filtering by user identifier to retrieve only resources belonging to a specific user.
# List spaces for a specific user
spaces = client.spaces.list(user="[email protected]", limit=20)
print(f"Found {len(spaces.items)} spaces")

# List sessions for a specific user
sessions = client.sessions.list(user="[email protected]", limit=20)
print(f"Found {len(sessions.items)} sessions")

# List disks for a specific user
disks = client.disks.list(user="[email protected]", limit=20)
print(f"Found {len(disks.items)} disks")

# List skills for a specific user
skills = client.skills.list_catalog(user="[email protected]", limit=20)
print(f"Found {len(skills.items)} skills")
Use user filtering to build user-specific dashboards and views.
3

Delete a user and all resources

Deleting a user removes the user record and cascades to delete all associated resources (Spaces, Sessions, Disks, and Skills).
# Delete a user and all their resources
client.users.delete("[email protected]")
print("User and all resources deleted")
Deleting a user is a destructive operation that cannot be undone. All Spaces, Sessions, Disks, and Skills associated with the user will be permanently deleted.

Complete example

Here’s a complete working example that demonstrates the full workflow:
import os
from acontext import AcontextClient, FileUpload

def main():
    # Initialize client
    client = AcontextClient(
        api_key=os.getenv("ACONTEXT_API_KEY"),
    )
    
    user_id = "[email protected]"
    
    try:
        # Create resources for a user
        space = client.spaces.create(
            user=user_id,
            configs={"name": "Demo Workspace"}
        )
        print(f"✓ Created space: {space.id}")
        
        session = client.sessions.create(
            user=user_id,
            space_id=space.id
        )
        print(f"✓ Created session: {session.id}")
        
        disk = client.disks.create(user=user_id)
        print(f"✓ Created disk: {disk.id}")
        
        # List all resources for the user
        spaces = client.spaces.list(user=user_id)
        sessions = client.sessions.list(user=user_id)
        disks = client.disks.list(user=user_id)
        print(f"✓ User has {len(spaces.items)} space(s), {len(sessions.items)} session(s), {len(disks.items)} disk(s)")
        
        # Cleanup: Delete user and all resources
        client.users.delete(user_id)
        print(f"✓ Deleted user {user_id} and all resources")
        
    except Exception as e:
        print(f"✗ Error: {e}")

if __name__ == "__main__":
    main()

Use cases

Multi-tenant Applications

Manage resources for multiple users in a single Acontext project without requiring separate API keys for each user.

Per-user Isolation

Query and manage resources for specific users, enabling user-specific dashboards and access control.

User Offboarding

Easily clean up all resources when a user leaves by deleting the user and cascading to all associated resources.

Usage Analytics

Track resource usage per user for billing, quotas, or analytics purposes.

How it works

When you create a resource with a user parameter:
  1. Acontext checks if a user with that identifier exists in the project
  2. If the user doesn’t exist, it creates a new user record automatically
  3. The resource is associated with the user via a foreign key
  4. If the user already exists, the existing user record is used
This means you don’t need to explicitly create users - they are created automatically when first referenced.
User identifiers are:
  • Strings: Any string value (e.g., email addresses, user IDs, usernames)
  • Unique per project: The same identifier can be used in different projects
  • Case-sensitive: [email protected] and [email protected] are different users
When you delete a user, the database’s foreign key constraints ensure that all associated resources are automatically deleted:
  • All Spaces associated with the user
  • All Sessions associated with the user
  • All Disks associated with the user
  • All Skills associated with the user
This is handled by the database’s ON DELETE CASCADE constraint, ensuring data consistency.
The Python SDK includes full async support for non-blocking operations:
import asyncio
from acontext import AsyncAcontextClient

async def main():
    async with AsyncAcontextClient(
        api_key=os.getenv("ACONTEXT_API_KEY"),
    ) as client:
        # All methods are async
        space = await client.spaces.create(user="[email protected]")
        spaces = await client.spaces.list(user="[email protected]")
        await client.users.delete("[email protected]")

asyncio.run(main())

Best practices

Use consistent identifier formats across your application (e.g., always use email addresses or always use user IDs).
# Good: Consistent email format
client.spaces.create(user="[email protected]")
client.sessions.create(user="[email protected]")

# Avoid: Inconsistent formats
client.spaces.create(user="[email protected]")
client.sessions.create(user="user_123")  # Different format for same user
Always inform users before deleting their data. The cascade deletion removes all associated resources permanently.

API Reference

Delete User

For details on creating and listing resources with user parameters, see the API reference for:

Troubleshooting

Problem: Resources exist but are not returned when filtering by user.Solution:
  • Verify the user identifier is spelled correctly (case-sensitive)
  • Ensure resources were created with the same user identifier
  • Check that you’re querying within the same project
Problem: Getting an error when trying to delete a user.Solution:
  • Verify the user identifier exists
  • Ensure you have the correct API key with permissions
  • URL-encode special characters in the identifier (e.g., @ becomes %40)
Problem: Resources were created but not associated with a user.Solution:
  • The user parameter must be provided at resource creation time
  • Resources cannot be retroactively associated with a user
  • Create new resources with the user parameter

Next Steps