Python SDK for SCS (Spyxpo Cloud Services)
pip install scs-sdkFor realtime functionality (WebSocket support):
pip install scs-sdk[realtime]from scs import SCS
# Initialize from config file
scs = SCS.initialize_app('./scs-info.json')
# Or initialize with config dict
scs = SCS({
'api_key': 'your-api-key',
'project_id': 'your-project-id',
'base_url': 'https://your-scs-instance.com'
})
# Authentication
user = scs.auth.login(email='user@example.com', password='password123')
# Database
users = scs.database.collection('users').where('age', '>=', 18).limit(10).get()
# Storage
scs.storage.upload('./image.png', folder='images')# Register a new user
user = scs.auth.register(
email='user@example.com',
password='password123',
display_name='John Doe'
)
# Login
user = scs.auth.login(email='user@example.com', password='password123')
# Get current user
me = scs.auth.get_current_user()
# Update profile
scs.auth.update_profile(display_name='Jane Doe')
# Change password
scs.auth.change_password(
current_password='old123',
new_password='new456'
)
# Logout
scs.auth.logout()SCS supports multiple OAuth providers for seamless social authentication. Each provider follows a similar pattern but requires different credentials obtained from their respective SDKs.
Authenticate users with their Google account. Requires the Google Sign-In SDK on the client.
# Sign in with Google
user = scs.auth.sign_in_with_google(
id_token='google-id-token', # Required: ID token from Google Sign-In
access_token='google-access-token' # Optional: Access token for additional scopes
)
print(f"User ID: {user['uid']}")
print(f"Email: {user['email']}")
print(f"Display Name: {user['displayName']}")
print(f"Photo URL: {user['photoURL']}")
print(f"Provider: {user['providerId']}") # 'google'Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
id_token |
str | Yes | The ID token obtained from Google Sign-In SDK |
access_token |
str | No | Access token for additional Google API scopes |
Returns: dict with user data and token
Example with Google OAuth Library:
from google.oauth2 import id_token
from google.auth.transport import requests
# Verify and get token on server side
def verify_google_token(token):
try:
idinfo = id_token.verify_oauth2_token(
token, requests.Request(), GOOGLE_CLIENT_ID
)
return idinfo
except ValueError:
return None
# Sign in with the token
user = scs.auth.sign_in_with_google(id_token=google_token)Authenticate users with their Facebook account.
# Sign in with Facebook
user = scs.auth.sign_in_with_facebook(
access_token='facebook-access-token' # Required: Access token from Facebook Login
)
print(f"User: {user['displayName']}")
print(f"Email: {user['email']}") # May be None if user didn't grant email permissionParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
access_token |
str | Yes | Access token from Facebook Login SDK |
Example with Facebook SDK:
# After getting access token from Facebook SDK on client
def facebook_login(access_token):
try:
user = scs.auth.sign_in_with_facebook(access_token=access_token)
return user
except Exception as e:
print(f"Facebook login failed: {e}")
return NoneAuthenticate users with their Apple ID. Ideal for iOS apps and required for apps with social login on the App Store.
# Sign in with Apple
user = scs.auth.sign_in_with_apple(
identity_token='apple-identity-token', # Required: Identity token from Sign in with Apple
authorization_code='apple-auth-code', # Optional: Authorization code for server verification
full_name='John Doe' # Optional: User's name (only available on first sign-in)
)Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
identity_token |
str | Yes | JWT identity token from Sign in with Apple |
authorization_code |
str | No | Authorization code for additional verification |
full_name |
str | No | User's full name (Apple only provides this on first sign-in) |
Important Notes:
- Apple only provides the user's name on the first sign-in. Store it immediately.
- Users can choose to hide their email (Apple provides a relay email).
- Required for apps using social login on iOS/macOS.
Authenticate users with their GitHub account. Popular for developer-focused applications.
# Sign in with GitHub
user = scs.auth.sign_in_with_github(
code='github-oauth-code', # Required: OAuth authorization code
redirect_uri='https://yourapp.com/callback' # Optional: Must match OAuth app settings
)
print(f"GitHub username: {user['displayName']}")
print(f"Email: {user['email']}")Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
code |
str | Yes | OAuth authorization code from GitHub OAuth flow |
redirect_uri |
str | No | Redirect URI (must match your GitHub OAuth App settings) |
OAuth Flow Example (Flask):
from flask import Flask, redirect, request
import requests
app = Flask(__name__)
GITHUB_CLIENT_ID = 'your-client-id'
GITHUB_CLIENT_SECRET = 'your-client-secret'
@app.route('/login/github')
def github_login():
return redirect(
f'https://github.com/login/oauth/authorize'
f'?client_id={GITHUB_CLIENT_ID}'
f'&redirect_uri=https://yourapp.com/callback'
f'&scope=read:user user:email'
)
@app.route('/callback')
def github_callback():
code = request.args.get('code')
if code:
user = scs.auth.sign_in_with_github(
code=code,
redirect_uri='https://yourapp.com/callback'
)
return f"Welcome, {user['displayName']}!"
return "Login failed"Authenticate users with their Twitter/X account using OAuth 1.0a.
# Sign in with Twitter/X
user = scs.auth.sign_in_with_twitter(
oauth_token='twitter-oauth-token', # Required: OAuth token
oauth_token_secret='twitter-oauth-secret' # Required: OAuth token secret
)Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
oauth_token |
str | Yes | OAuth token from Twitter authentication |
oauth_token_secret |
str | Yes | OAuth token secret from Twitter authentication |
Note: Twitter uses OAuth 1.0a which requires a more complex flow. Consider using a library like tweepy or python-twitter.
Authenticate users with their Microsoft account (personal, work, or school accounts).
# Sign in with Microsoft
user = scs.auth.sign_in_with_microsoft(
access_token='microsoft-access-token', # Required: Access token from MSAL
id_token='microsoft-id-token' # Optional: ID token for additional claims
)Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
access_token |
str | Yes | Access token from Microsoft Authentication Library (MSAL) |
id_token |
str | No | ID token for additional user claims |
Example with MSAL Python:
from msal import ConfidentialClientApplication
app = ConfidentialClientApplication(
client_id="your-client-id",
authority="https://login.microsoftonline.com/common",
client_credential="your-client-secret"
)
# After getting tokens from authorization code flow
result = app.acquire_token_by_authorization_code(
code,
scopes=["User.Read"],
redirect_uri="https://yourapp.com/callback"
)
if "access_token" in result:
user = scs.auth.sign_in_with_microsoft(
access_token=result["access_token"],
id_token=result.get("id_token")
)Allow users to use your app without creating an account. Anonymous accounts can later be upgraded to permanent accounts by linking a provider.
# Sign in anonymously (creates a temporary account)
user = scs.auth.sign_in_anonymously(
custom_data={'referrer': 'landing-page', 'campaign': 'summer-sale'} # optional
)
print(f"Anonymous user ID: {user['uid']}")
print(f"Is anonymous: {user['isAnonymous']}") # TrueParameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
custom_data |
dict | No | Custom data to store with the anonymous user for analytics |
Use Cases:
- Allow users to try your app before signing up
- Guest checkout in e-commerce
- Save user progress/preferences before account creation
- A/B testing with user tracking
Converting Anonymous to Permanent Account:
# User decides to create a permanent account
# Link their anonymous account to a provider
try:
user = scs.auth.link_provider('google', {
'idToken': 'google-id-token'
})
print("Account upgraded! User data preserved.")
print(f"Is anonymous: {user['isAnonymous']}") # False
except Exception as e:
if 'credential-already-in-use' in str(e):
# This Google account is already linked to another user
print("This account is already registered. Please sign in instead.")
else:
raiseTwo-step authentication flow using SMS verification codes.
# Step 1: Send verification code to phone
result = scs.auth.send_phone_verification_code(
phone_number='+1234567890', # Required: E.164 format
recaptcha_token='recaptcha-token' # Optional: For bot protection
)
verification_id = result['verificationId']
print(f"Verification ID: {verification_id}")
# Store this ID - you'll need it in step 2
# Step 2: User enters the code they received
user = scs.auth.sign_in_with_phone_number(
verification_id=verification_id, # The ID from step 1
code='123456' # 6-digit code from SMS
)
print(f"Phone verified: {user['phoneNumber']}")send_phone_verification_code Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
phone_number |
str | Yes | Phone number in E.164 format (e.g., +1234567890) |
recaptcha_token |
str | No | reCAPTCHA token for abuse prevention |
sign_in_with_phone_number Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
verification_id |
str | Yes | Verification ID from send_phone_verification_code |
code |
str | Yes | 6-digit verification code from SMS |
Complete Flow Example:
def sign_in_with_phone(phone_number: str, get_code_callback) -> dict:
"""
Sign in with phone number.
Args:
phone_number: Phone number in E.164 format
get_code_callback: Function that prompts user for the SMS code
Returns:
User dict on success
"""
try:
# Step 1: Send code
result = scs.auth.send_phone_verification_code(
phone_number=phone_number
)
verification_id = result['verificationId']
# Get code from user (your UI implementation)
code = get_code_callback()
# Step 2: Verify code
user = scs.auth.sign_in_with_phone_number(
verification_id=verification_id,
code=code
)
return user
except Exception as e:
error_msg = str(e).lower()
if 'invalid-phone-number' in error_msg:
raise ValueError('Invalid phone number format. Use E.164 format (+1234567890)')
elif 'too-many-requests' in error_msg:
raise ValueError('Too many attempts. Please try again later.')
elif 'invalid-verification-code' in error_msg:
raise ValueError('Invalid verification code. Please try again.')
elif 'code-expired' in error_msg:
raise ValueError('Code expired. Please request a new one.')
else:
raiseSign in using a JWT token generated by your own backend. Useful for migrating users from another system or integrating with custom authentication.
# Sign in with a custom token (generated by your backend)
user = scs.auth.sign_in_with_custom_token('your-custom-jwt-token')
print(f"Signed in user: {user['uid']}")Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
token |
str | Yes | JWT token generated by your backend |
Backend Token Generation Example:
import jwt
import time
import os
def create_custom_token(uid: str, claims: dict = None) -> str:
"""
Create a custom authentication token.
Args:
uid: Unique user identifier
claims: Optional custom claims to include
Returns:
JWT token string
"""
payload = {
'uid': uid,
'claims': claims or {},
'iat': int(time.time()),
'exp': int(time.time()) + 3600 # 1 hour
}
return jwt.encode(
payload,
os.environ['SCS_SECRET_KEY'],
algorithm='HS256'
)
# Generate token for a user
custom_token = create_custom_token('user-123', {'role': 'admin'})
# Send this token to the client for sign-inUse Cases:
- Migrating users from another authentication system
- Server-side user creation with immediate client sign-in
- Integration with enterprise SSO systems (SAML, LDAP)
- Machine-to-machine authentication
Link multiple authentication providers to a single account. Users can sign in with any linked provider.
# Link a provider to current account
user = scs.auth.link_provider('facebook', {
'accessToken': 'facebook-access-token'
})
print(f"Linked providers: {user['providerData']}")
# [{'providerId': 'password'}, {'providerId': 'google'}, {'providerId': 'facebook'}]
# Unlink a provider from current account
user = scs.auth.unlink_provider('facebook')
print(f"Remaining providers: {user['providerData']}")
# Get available sign-in methods for an email
result = scs.auth.fetch_sign_in_methods_for_email('user@example.com')
print(f"Available methods: {result['methods']}")
# ['password', 'google', 'facebook']link_provider Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
provider |
str | Yes | Provider name: 'google', 'facebook', 'apple', 'github', 'twitter', 'microsoft' |
credentials |
dict | Yes | Provider-specific credentials (tokens) |
Supported Providers and Credentials:
| Provider | Required Credentials |
|---|---|
google |
{'idToken': '...', 'accessToken': '...'} (accessToken optional) |
facebook |
{'accessToken': '...'} |
apple |
{'identityToken': '...', 'authorizationCode': '...', 'fullName': '...'} |
github |
{'code': '...', 'redirectUri': '...'} |
twitter |
{'oauthToken': '...', 'oauthTokenSecret': '...'} |
microsoft |
{'accessToken': '...', 'idToken': '...'} |
Complete Account Linking Flow:
def can_link_provider(email: str, provider: str) -> bool:
"""Check if a provider can be linked to an account."""
result = scs.auth.fetch_sign_in_methods_for_email(email)
methods = result.get('methods', [])
if provider in methods:
raise ValueError(f"{provider} is already linked to this account")
return True
def link_google_account(google_id_token: str) -> dict:
"""Link Google to the current user's account."""
try:
# Verify user is signed in
current_user = scs.auth.get_current_user()
if not current_user:
raise ValueError('Must be signed in to link accounts')
# Link the provider
user = scs.auth.link_provider('google', {
'idToken': google_id_token
})
print('Successfully linked Google account')
return user
except Exception as e:
error_msg = str(e).lower()
if 'credential-already-in-use' in error_msg:
print('This Google account is already linked to another user')
elif 'provider-already-linked' in error_msg:
print('Google is already linked to this account')
raiseHandle password recovery and email verification flows.
# Send password reset email
scs.auth.send_password_reset_email('user@example.com')
print("Password reset email sent")
# Confirm password reset (user clicks link in email, you extract the code)
scs.auth.confirm_password_reset(
code='reset-code-from-email', # Code from the reset link
new_password='newSecurePassword123' # User's new password
)
print("Password successfully reset")
# Send email verification to current user
scs.auth.send_email_verification()
print("Verification email sent")
# Verify email with code (user clicks link, you extract the code)
scs.auth.verify_email('verification-code')
print("Email verified")Error Handling:
def reset_password(email: str) -> dict:
"""Send password reset email with error handling."""
try:
scs.auth.send_password_reset_email(email)
return {'success': True, 'message': 'Reset email sent'}
except Exception as e:
error_msg = str(e).lower()
if 'user-not-found' in error_msg:
# Don't reveal if user exists for security
return {'success': True, 'message': 'If this email exists, a reset link was sent'}
elif 'too-many-requests' in error_msg:
return {'success': False, 'message': 'Too many attempts. Please try later.'}
else:
raise
def confirm_reset(code: str, new_password: str) -> dict:
"""Confirm password reset with validation."""
# Validate password strength
if len(new_password) < 8:
raise ValueError('Password must be at least 8 characters')
try:
scs.auth.confirm_password_reset(code=code, new_password=new_password)
return {'success': True}
except Exception as e:
error_msg = str(e).lower()
if 'expired-action-code' in error_msg:
return {'success': False, 'message': 'Reset link expired. Please request a new one.'}
elif 'invalid-action-code' in error_msg:
return {'success': False, 'message': 'Invalid reset link.'}
elif 'weak-password' in error_msg:
return {'success': False, 'message': 'Password is too weak.'}
else:
raiseManage user sessions and authentication state.
# Check if user is logged in
is_logged_in = scs.auth.is_logged_in
print(f"Is logged in: {is_logged_in}")
# Get current user (from cache)
cached_user = scs.auth.current_user
# Get current user (fresh from server)
user = scs.auth.get_current_user()
# Refresh user data
refreshed_user = scs.auth.reload()
# Get the current auth token
token = scs.auth.tokenfrom scs import SCS, AuthenticationError
class AuthService:
def __init__(self):
self.scs = SCS({
'api_key': 'your-api-key',
'project_id': 'your-project-id',
'base_url': 'https://your-scs-instance.com'
})
def register(self, email: str, password: str, display_name: str) -> dict:
"""Register a new user with email verification."""
user = self.scs.auth.register(
email=email,
password=password,
display_name=display_name
)
# Send verification email
self.scs.auth.send_email_verification()
return user
def login(self, email: str, password: str) -> dict:
"""Login with email and password."""
return self.scs.auth.login(email=email, password=password)
def social_login(self, provider: str, credentials: dict) -> dict:
"""Login with any social provider."""
methods = {
'google': lambda: self.scs.auth.sign_in_with_google(**credentials),
'facebook': lambda: self.scs.auth.sign_in_with_facebook(**credentials),
'apple': lambda: self.scs.auth.sign_in_with_apple(**credentials),
'github': lambda: self.scs.auth.sign_in_with_github(**credentials),
'twitter': lambda: self.scs.auth.sign_in_with_twitter(**credentials),
'microsoft': lambda: self.scs.auth.sign_in_with_microsoft(**credentials)
}
if provider not in methods:
raise ValueError(f"Unknown provider: {provider}")
return methods[provider]()
def continue_as_guest(self, custom_data: dict = None) -> dict:
"""Sign in anonymously for guest access."""
return self.scs.auth.sign_in_anonymously(custom_data=custom_data or {})
def upgrade_guest_account(self, provider: str, credentials: dict) -> dict:
"""Upgrade anonymous account to permanent."""
user = self.scs.auth.get_current_user()
if not user or not user.get('isAnonymous'):
raise ValueError('Current user is not anonymous')
return self.scs.auth.link_provider(provider, credentials)
def logout(self):
"""Sign out the current user."""
self.scs.auth.logout()
# Usage
auth = AuthService()
# Register new user
user = auth.register('user@example.com', 'password123', 'John Doe')
# Or sign in with Google
google_user = auth.social_login('google', {'id_token': 'xxx'})
# Or continue as guest and upgrade later
guest = auth.continue_as_guest({'source': 'homepage'})
# ... user decides to create account ...
upgraded = auth.upgrade_guest_account('google', {'idToken': 'xxx'})Document database with query builder. SCS supports two powerful database options:
| Type | Name | Description | Best For |
|---|---|---|---|
eazi |
eaZI Database | Document-based NoSQL with Firestore-like collections, documents, and subcollections | Development, prototyping, small to medium apps |
reladb |
RelaDB | Production-grade NoSQL database with relational-style views | Production, scalability, advanced queries |
from scs import SCS
# eaZI is the default database - no special configuration needed
scs = SCS({
'project_id': 'your-project-id',
'api_key': 'your-api-key'
# database_type: 'eazi' is implicit
})from scs import SCS
# Use RelaDB for production
scs = SCS({
'project_id': 'your-project-id',
'api_key': 'your-api-key',
'database_type': 'reladb' # Enable RelaDB
})- Document-based: Firestore-like collections and documents
- Subcollections: Nested data organization
- File-based storage: No external dependencies required
- Zero configuration: Works out of the box
- Query support: Filtering, ordering, and pagination
- Production-ready: Built for reliability and performance
- Scalable: Horizontal scaling and replication support
- Advanced queries: Aggregation pipelines, complex filters
- Indexing: Custom indexes for optimized performance
- Schema flexibility: Dynamic schema with validation support
- Relational-style views: Table view with columns and rows in the console
# Get a collection reference
users = scs.database.collection('users')
# List all collections
collections = scs.database.list_collections()
# Create a collection
scs.database.create_collection('new_collection')
# Delete a collection
scs.database.delete_collection('old_collection')# Add document with auto-generated ID
doc = scs.database.collection('users').add({
'name': 'John Doe',
'email': 'john@example.com',
'age': 30,
'tags': ['developer', 'python'],
'profile': {
'bio': 'Software developer',
'avatar': 'https://example.com/avatar.jpg'
}
})
print(f'Document ID: {doc["id"]}')
# Set document with custom ID (creates or overwrites)
scs.database.collection('users').doc('user-123').set({
'name': 'Jane Doe',
'email': 'jane@example.com'
})
# Get a single document
user = scs.database.collection('users').doc('user-123').get()
print(user)
# Update document (partial update)
scs.database.collection('users').doc('user-123').update({
'age': 31,
'profile.bio': 'Senior developer'
})
# Delete document
scs.database.collection('users').doc('user-123').delete()# Simple query with single filter
active_users = scs.database.collection('users') \
.where('status', '==', 'active') \
.get()
# Multiple filters
results = scs.database.collection('users') \
.where('age', '>=', 18) \
.where('status', '==', 'active') \
.get()
# Ordering and pagination
posts = scs.database.collection('posts') \
.where('published', '==', True) \
.order_by('created_at', 'desc') \
.limit(10) \
.skip(20) \
.get()
# Using 'in' operator
featured = scs.database.collection('posts') \
.where('category', 'in', ['tech', 'science', 'news']) \
.get()
# Using 'contains' for array fields
tagged = scs.database.collection('posts') \
.where('tags', 'contains', 'python') \
.get()| Operator | Description | Example |
|---|---|---|
== |
Equal to | .where('status', '==', 'active') |
!= |
Not equal to | .where('status', '!=', 'deleted') |
> |
Greater than | .where('age', '>', 18) |
>= |
Greater than or equal | .where('age', '>=', 18) |
< |
Less than | .where('price', '<', 100) |
<= |
Less than or equal | .where('price', '<=', 50) |
in |
Value in array | .where('status', 'in', ['active', 'pending']) |
contains |
Array contains value | .where('tags', 'contains', 'featured') |
# Access a subcollection
posts_ref = scs.database \
.collection('users') \
.doc('user_id') \
.collection('posts')
# Add to subcollection
post = posts_ref.add({
'title': 'My First Post',
'content': 'Hello World!',
'created_at': datetime.now().isoformat()
})
# Query subcollection
user_posts = posts_ref \
.order_by('created_at', 'desc') \
.limit(5) \
.get()
# Nested subcollections (e.g., users/user_id/posts/post_id/comments)
comments_ref = scs.database \
.collection('users') \
.doc('user_id') \
.collection('posts') \
.doc('post_id') \
.collection('comments')# Upload from file path
file_info = scs.storage.upload('./image.png')
# Upload with folder
file_info = scs.storage.upload('./doc.pdf', folder='documents')
# Upload from bytes
file_info = scs.storage.upload_bytes(
data=image_bytes,
filename='image.png',
content_type='image/png'
)
# List files
files = scs.storage.list_files(folder='images')
# Get file reference
file_ref = scs.storage.ref('file-id')
# Download file
content = file_ref.download()
# Download to file
file_ref.download_to_file('./local_file.png')
# Get metadata
metadata = file_ref.get_metadata()
# Delete file
file_ref.delete()
# Folder operations
scs.storage.create_folder('my-folder')
scs.storage.delete_folder('my-folder')Real-time data synchronization via WebSocket:
# Connect to realtime service
scs.realtime.connect()
# Get reference
chat_ref = scs.realtime.ref('chat/room1')
# Subscribe to updates
def on_message(data, event):
print(f'Event: {event}, Data: {data}')
unsubscribe = chat_ref.on(on_message)
# Subscribe to single update
chat_ref.once(lambda data, event: print(data))
# Unsubscribe
unsubscribe()
# Disconnect
scs.realtime.disconnect()Push notifications with topics and direct messaging:
# Register device token
scs.messaging.register_token(
token='device-fcm-token',
platform='android'
)
# Topic operations
scs.messaging.create_topic('news', description='News updates')
scs.messaging.subscribe_to_topic('news', 'device-token')
scs.messaging.unsubscribe_from_topic('news', 'device-token')
# Send to topic
scs.messaging.send_to_topic(
topic='news',
title='Breaking News',
body='Something happened!',
data={'articleId': '123'}
)
# Send to specific device
scs.messaging.send_to_token(
token='device-token',
title='Personal Alert',
body='You have a new message'
)
# Send to multiple devices
scs.messaging.send_to_tokens(
tokens=['token1', 'token2'],
title='Broadcast',
body='Hello everyone!'
)Dynamic app configuration:
# Fetch configuration
config = scs.remote_config.fetch()
# Get values with type safety
theme = scs.remote_config.get_string('app_theme', default='light')
max_items = scs.remote_config.get_int('max_items', default=10)
enabled = scs.remote_config.get_bool('feature_enabled', default=False)
settings = scs.remote_config.get_json('settings', default={})
# Admin: Manage parameters
scs.remote_config.create_param(
key='app_theme',
value='dark',
description='Default app theme'
)
scs.remote_config.update_param('app_theme', 'light')
scs.remote_config.delete_param('old_param')
# Publish changes
scs.remote_config.publish()
# Version management
versions = scs.remote_config.list_versions()
scs.remote_config.rollback('version-id')Execute custom code on the backend:
# Invoke a function
result = scs.functions.invoke('processOrder', {
'orderId': '12345',
'action': 'confirm'
})
# Admin: Create a function
scs.functions.create(
name='processOrder',
code='''
module.exports = async (data, context) => {
const { orderId, action } = data;
// Process order...
return { success: true, orderId };
};
''',
runtime='nodejs18',
timeout=30000,
memory=256
)
# Admin: List functions
functions = scs.functions.list()
# Admin: Update function
scs.functions.update('function-id', code='...')
# Admin: Test function
result = scs.functions.test('function-id', {'test': 'data'})
# Admin: Get logs
logs = scs.functions.get_logs('function-id')Chat, text completion, and image generation with local LLM models:
# Chat with AI
response = scs.ai.chat(
message="What is the capital of France?",
system_prompt="You are a helpful geography assistant."
)
print(response['content'])
# Text completion
response = scs.ai.complete(prompt="Once upon a time")
print(response['content'])
# Generate image
response = scs.ai.generate_image(prompt="A sunset over mountains")
print(response['imageUrl'])
# List available models
models = scs.ai.list_models()
# Conversation management
conversation = scs.ai.create_conversation(title="Geography Chat")
scs.ai.get_conversation(conversation['conversationId'])
scs.ai.delete_conversation(conversation['conversationId'])Create and manage AI agents with custom instructions and tools:
# Create an agent
agent = scs.ai.create_agent(
name="Customer Support",
instructions="You are a helpful customer support assistant. Be polite and helpful.",
model="llama3.2",
temperature=0.7
)
print(f"Created agent: {agent['agentId']}")
# List agents
agents = scs.ai.list_agents()
# Run the agent
response = scs.ai.run_agent(
agent_id=agent['agentId'],
input="How do I reset my password?"
)
print(f"Agent: {response['output']}")
print(f"Session: {response['sessionId']}")
# Continue the conversation in the same session
response = scs.ai.run_agent(
agent_id=agent['agentId'],
input="Thanks! What about enabling 2FA?",
session_id=response['sessionId']
)
# List agent sessions
sessions = scs.ai.list_agent_sessions(agent['agentId'])
# Get full session history
session = scs.ai.get_agent_session(agent['agentId'], response['sessionId'])
for msg in session['messages']:
print(f"{msg['role']}: {msg['content']}")
# Update agent
scs.ai.update_agent(
agent_id=agent['agentId'],
instructions="Updated instructions here",
temperature=0.5
)
# Define a tool for agents
tool = scs.ai.define_tool(
name="get_weather",
description="Get weather for a location",
parameters={
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
}
}
)
# List tools
tools = scs.ai.list_tools()
# Delete agent and sessions
scs.ai.delete_agent_session(agent['agentId'], response['sessionId'])
scs.ai.delete_agent(agent['agentId'])Create an scs-info.json file:
{
"sdk_config": {
"api_key": "pk_your_api_key",
"project_id": "your-project-id",
"base_url": "https://your-scs-instance.com"
}
}from scs import SCS, SCSError, AuthenticationError, NotFoundError, ValidationError
try:
user = scs.auth.login(email='user@example.com', password='wrong')
except AuthenticationError as e:
print(f'Auth failed: {e.message}')
print(f'Status: {e.status}')
except NotFoundError as e:
print(f'Not found: {e.message}')
except ValidationError as e:
print(f'Validation error: {e.message}')
except SCSError as e:
print(f'SCS error: {e.message}')with SCS({'api_key': '...', 'project_id': '...'}) as scs:
users = scs.database.collection('users').get()
# Connection automatically closed- Python 3.8+
- requests
- python-socketio[client] (optional, for realtime functionality)
MIT License