> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cocobase.cc/llms.txt
> Use this file to discover all available pages before exploring further.

# Python SDK

> Complete guide to using Cocobase with Python

# Python SDK

Complete guide to using Cocobase with Python applications and Cloud Functions.

## Installation

```bash theme={null}
pip install cocobase
```

## Quick Start

### Initialize Cocobase

```python theme={null}
from cocobase_client.client import CocoBaseClient

db = CocoBaseClient(
    api_key="YOUR_API_KEY",
    project_id="YOUR_PROJECT_ID",  # required for cloud functions
    base_url="https://api.cocobase.cc"  # Optional
)
```

### Basic Operations

```python theme={null}
# List documents
docs = db.list_documents("posts")

# Get single document
doc = db.get_document("posts", "doc-id")

# Create document
created = db.create_document("posts", {
    "title": "My First Post",
    "content": "Hello World!"
})

# Update document
db.update_document("posts", "doc-id", {
    "title": "Updated Title"
})

# Delete document
db.delete_document("posts", "doc-id")
```

***

## Querying Data

### Simple Filters

```python theme={null}
# Find active users older than 18
query = QueryBuilder().eq("status", "active").gt("age", 18)
users = db.list_documents("users", query=query)
```

### Query Builder

```python theme={null}
from cocobase_client.query import QueryBuilder

query = (QueryBuilder()
    .eq("status", "active")
    .gt("age", 18)
    .contains("email", "@gmail.com")
    .limit(10))

users = db.list_documents("users", query=query)
```

***

## Operators Reference

### Comparison Operators

| Operator         | Filter Key   | Example                     |
| ---------------- | ------------ | --------------------------- |
| Equal            | `field`      | `{"status": "active"}`      |
| Greater Than     | `field__gt`  | `{"age__gt": 18}`           |
| Greater or Equal | `field__gte` | `{"age__gte": 18}`          |
| Less Than        | `field__lt`  | `{"age__lt": 65}`           |
| Less or Equal    | `field__lte` | `{"age__lte": 65}`          |
| Not Equal        | `field__ne`  | `{"status__ne": "deleted"}` |

### String Operators

| Operator    | Filter Key          | Example                          |
| ----------- | ------------------- | -------------------------------- |
| Contains    | `field__contains`   | `{"title__contains": "python"}`  |
| Starts With | `field__startswith` | `{"email__startswith": "admin"}` |
| Ends With   | `field__endswith`   | `{"domain__endswith": ".com"}`   |

### Array Operators

| Operator     | Filter Key     | Example                                 |
| ------------ | -------------- | --------------------------------------- |
| In Array     | `field__in`    | `{"status__in": "active,pending"}`      |
| Not In Array | `field__notin` | `{"status__notin": "deleted,archived"}` |

***

## Sorting and Pagination

### Sorting

```python theme={null}
# Sort by creation date (newest first)
query = QueryBuilder().from_dict({"sort": "createdAt", "order": "desc"})
posts = db.list_documents("posts", query=query)
```

### Pagination

```python theme={null}
# Get page 3 (20 items per page)
query = QueryBuilder().limit(20).offset(40)
posts = db.list_documents("posts", query=query)
```

***

## Working with Dataclasses

### Define Your Types

```python theme={null}
from dataclasses import dataclass
from typing import Optional

@dataclass
class Book:
    title: str
    author: str
    price: float
    published_at: Optional[str] = None

    @classmethod
    def from_dict(cls, data: dict) -> "Book":
        return cls(
            title=data["title"],
            author=data["author"],
            price=data["price"],
            published_at=data.get("publishedAt")
        )

    def to_dict(self) -> dict:
        return {
            "title": self.title,
            "author": self.author,
            "price": self.price,
            "publishedAt": self.published_at
        }
```

### Create with Dataclasses

```python theme={null}
new_book = Book(
    title="Clean Code",
    author="Robert Martin",
    price=45.99
)

created = db.create_document("books", new_book.to_dict())
```

### Parse Response to Dataclass

```python theme={null}
doc = db.get_document("books", "doc-id")
book = Book.from_dict(doc.data)
print(book.title)
```

***

## Authentication

### Email/Password

```python theme={null}
# Register
result = db.auth.register(
    "user@example.com",
    "securePassword123",
    {"username": "johndoe"}  # optional extra data
)

# Login
result = db.auth.login("user@example.com", "securePassword123")

# Logout
db.auth.logout()

# Get current user
current_user = db.auth.get_current_user()

# Check authentication
if db.auth.is_authenticated():
    print("Logged in")
```

### OAuth

```python theme={null}
# Google OAuth
user = db.auth.login_with_google(
    id_token="google-id-token",
    platform="web"  # or "mobile", "ios", "android"
)

# GitHub OAuth
user = db.auth.login_with_github(
    code="github-auth-code",
    redirect_uri="https://yourapp.com/callback",
    platform="web"
)
```

## Advanced Auth

### Register with Files

```python theme={null}
result = db.auth.register_with_files(
    email="john@example.com",
    password="password123",
    data={"username": "johndoe"},
    files={"avatar": avatar_file}
)
```

### Update User

```python theme={null}
updated_user = db.auth.update_user(
    data={"bio": "Updated bio"},
    email="newemail@example.com"
)
```

### Update User with Files

```python theme={null}
updated_user = db.auth.update_user_with_files(
    data={"bio": "Updated bio"},
    files={"avatar": new_avatar_file}
)
```

### Two-Factor Authentication (2FA)

```python theme={null}
# Enable 2FA
db.auth.enable_2fa()

# Disable 2FA
db.auth.disable_2fa()

# Verify 2FA login
user = db.auth.verify_2fa_login(
    email="user@example.com",
    code="123456"
)
```

### Role Checking

```python theme={null}
if db.auth.has_role("admin"):
    print("User is an admin")
```

### List Users

```python theme={null}
users = db.auth.list_users({"limit": 10, "offset": 0})
```

### Get User by ID

```python theme={null}
user = db.auth.get_user_by_id("user-id")
```

***

## Cloud Functions

The Python SDK is primarily used in Cocobase Cloud Functions.

### Basic Cloud Function

```python theme={null}
def main():
    from cocobase_client.client import CocoBaseClient
    from cocobase_client.query import QueryBuilder

    db = CocoBaseClient()  # Auto-configured in cloud environment

    # Your function logic here
    query = QueryBuilder().limit(10)
    docs = db.list_documents("posts", query=query)

    return {
        "success": True,
        "count": len(docs)
    }
```

### Triggered Cloud Function

```python theme={null}
def main(event):
    from cocobase_client.client import CocoBaseClient

    db = CocoBaseClient()

    # Access trigger data
    document = event.get("document")
    trigger_type = event.get("type")

    if trigger_type == "created":
        docs = db.list_documents("users")
        db.create_document("logs", {
            "action": "user_created",
            "userId": document.get("id")
        })

    return {"success": True}
```

### Scheduled Cloud Function

```python theme={null}
def main():
    from cocobase_client.client import CocoBaseClient
    from cocobase_client.query import QueryBuilder
    from datetime import datetime, timedelta

    db = CocoBaseClient()

    # Clean up old documents
    cutoff = (datetime.now() - timedelta(days=30)).isoformat()

    query = QueryBuilder().from_dict({"createdAt__lt": cutoff}).limit(100)
    old_docs = db.list_documents("logs", query=query)

    for doc in old_docs:
        db.delete_document("logs", doc.id)

    return {
        "success": True,
        "deleted": len(old_docs)
    }
```

***

## Error Handling

```python theme={null}
from cocobase_client.exceptions import CocobaseError

try:
    doc = db.get_document("posts", "non-existent-id")
except CocobaseError as e:
    print(f"Error: {e}")
```

***

## Best Practices

### 1. Use Dataclasses for Type Safety

```python theme={null}
# Good
@dataclass
class Post:
    title: str
    content: str

post = Post.from_dict(doc.data)
print(post.title)

# Avoid
print(doc.data["title"])
```

### 2. Always Handle Errors

```python theme={null}
try:
    doc = db.get_document("posts", post_id)
    return doc
except CocobaseError as e:
    logger.error(f"Failed to get post: {e}")
    raise
```

### 3. Use Environment Variables

```python theme={null}
import os

db = CocoBaseClient(
    api_key=os.environ.get("COCOBASE_API_KEY")
)
```

### 4. Always Set Limits

```python theme={null}
from cocobase_client.query import QueryBuilder

# Good
query = QueryBuilder().limit(20)
docs = db.list_documents("posts", query=query)

# Bad - could return thousands
docs = db.list_documents("posts")
```

***

## Next Steps

* [Cloud Functions](/cloud-functions/introduction) - Build serverless functions
* [JavaScript SDK](/sdk-reference/javascript) - Learn about the JS/TS SDK
* [Flutter SDK](/sdk-reference/flutter) - Learn about the Flutter SDK
* [Authentication](/core-concepts/authentication) - Deep dive into auth
