Skip to main content

Cloud Function Environment

Complete guide to the execution environment, request handling, and response types in CocoBase cloud functions.

Overview

CocoBase cloud functions execute in a sandboxed Python 3.10 environment with access to:
  • Request object (request or req) - Access to query params, payload, headers, user info
  • Database service (db) - Query and manage your data
  • Template renderer (render) - Render HTML with Jinja2
  • Environment object (env) - Project and environment info

Function Execution

Execution URL

When you create a cloud function, you get an execution URL:
https://api.cocobase.buzz/functions/{function_id}/execute

HTTP Methods

GET Request:
# Query parameters in URL
curl "https://api.cocobase.buzz/functions/abc123/execute?name=John&age=25"
POST Request:
# JSON payload in body
curl -X POST https://api.cocobase.buzz/functions/abc123/execute \
  -H "Content-Type: application/json" \
  -d '{"name": "John", "age": 25}'

The request Object

The request object (also available as req) provides access to incoming request data.

Properties

def main():
    # Get data from POST body or GET query params
    name = req.get('name', 'Guest')
    age = req.get('age', 0)

    # Access all payload data
    all_data = req.json()

    # Get query parameters (GET requests)
    page = req.query_params.get('page', '1')

    # Access headers
    auth_token = req.headers.get('authorization', '')

    # Check HTTP method
    method = req.method  # 'GET' or 'POST'

    # Request timestamp
    timestamp = req.timestamp

    # Current user (if authenticated)
    user = req.user  # AppUser object or None

    # Project ID
    project_id = req.proj

Methods

request.get(key, default=None)

Get value from payload (POST) or query params (GET):
def main():
    # From POST body: {"name": "John"}
    # Or GET query: ?name=John
    name = req.get('name', 'Anonymous')

    return {"greeting": f"Hello, {name}!"}

request.json()

Get entire payload as dictionary:
def main():
    data = req.json()
    # Returns: {"name": "John", "age": 25, "email": "[email protected]"}

    return {
        "received": data,
        "keys": list(data.keys())
    }

request.send_mail()

Send email using CocoMailer integration:
def main():
    # Send with template
    result = req.send_mail(
        to="[email protected]",
        subject="Welcome!",
        template_id="welcome-template",
        context={
            "username": "John",
            "activation_link": "https://..."
        }
    )

    # Send with plain body
    result = req.send_mail(
        to=["[email protected]", "[email protected]"],
        subject="Notification",
        body="<h1>Hello!</h1><p>This is your notification.</p>"
    )

    return {"email_sent": result}

User Authentication

Access authenticated user data:
def main():
    user = req.user

    if not user:
        return {"error": "Authentication required"}, 401

    # User properties
    user_id = user.id
    email = user.email
    user_data = user.data  # Custom user fields
    roles = user.roles

    return {
        "user_id": user_id,
        "email": email,
        "roles": roles
    }

Response Types

JSON Response (Default)

Return a dictionary to send JSON:
def main():
    return {
        "success": True,
        "message": "Operation completed",
        "data": {"id": "123", "name": "John"}
    }

HTML Response

Use render.render_html() for HTML pages:
def main():
    html = '''
    <!DOCTYPE html>
    <html>
    <head>
        <title>My Page</title>
    </head>
    <body>
        <h1>Hello World!</h1>
    </body>
    </html>
    '''

    return render.render_html(html)

HTML with Template Variables

def main():
    posts = db.query("posts", status="published", limit=10)

    html = '''
    <!DOCTYPE html>
    <html>
    <body>
        <h1>Blog Posts</h1>
        {% for post in posts %}
        <article>
            <h2>{{ post.title }}</h2>
            <p>By {{ post.author.name }}</p>
        </article>
        {% endfor %}
    </body>
    </html>
    '''

    return render.render_html(html, {
        'posts': posts['data']
    })

Status Codes

Return a tuple with status code:
def main():
    user = req.user

    if not user:
        return {"error": "Unauthorized"}, 401

    if not user.is_admin:
        return {"error": "Forbidden"}, 403

    return {"success": True}, 200

Environment Variables

Access environment and project information:
def main():
    # Project ID
    project_id = env.project_id

    # Execution environment
    runtime = env.runtime  # "python3.10"

    # Static files base URL
    static_url = env.static_base_url

    return {
        "project": project_id,
        "runtime": runtime
    }

Available Python Modules

Cloud functions have access to these Python standard library modules without import statements:
ModuleDescriptionCommon Uses
jsonJSON encoding/decodingParse API responses, serialize data
datetimeDate and time classCurrent time, timestamps
timedeltaTime duration classAdd/subtract time, expiration
timeTime utilitiesDelays, timestamps, timing
mathMathematical functionsCalculations, rounding
reRegular expressionsPattern matching, validation
secretsCryptographically secure randomOTP generation, tokens, passwords
uuidUUID generationUnique identifiers
hashlibHash functionsMD5, SHA256, data integrity
base64Base64 encodingEncode/decode binary data
stringString constantsASCII letters, digits, punctuation
collectionsData structuresCounter, defaultdict, deque

Examples

OTP Generation (Secure):
def main():
    # Generate 6-digit OTP (cryptographically secure)
    otp = ''.join([str(secrets.randbelow(10)) for _ in range(6)])

    # Send via email
    req.send_mail(
        to=req.get('email'),
        subject="Your OTP Code",
        body=f"Your OTP is: {otp}"
    )

    return {"otp_sent": True}
Email Validation:
def main():
    email = req.get('email')

    # Validate email format
    email_pattern = r'^[\w\.-]+@[\w\.-]+\.\w+$'
    is_valid = bool(re.match(email_pattern, email))

    if not is_valid:
        return {"error": "Invalid email format"}, 400

    return {"valid": True}
Password Hashing:
def main():
    password = req.get('password')

    # Hash password with SHA256
    hashed = hashlib.sha256(password.encode()).hexdigest()

    return {"hash": hashed}

Error Handling

def main():
    try:
        result = some_operation()
        return {"result": result}
    except ValueError as e:
        return {"error": str(e)}, 400
    except Exception as e:
        print(f"Error: {str(e)}")
        return {"error": "Internal server error"}, 500

Next Steps