Python SDK for SCS (Spyxpo Cloud Services)
pip install scs-sdkFor realtime functionality (WebSocket support):
pip install scs-sdk[realtime]fromscsimportSCS# Initialize from config filescs=SCS.initialize_app('./scs-info.json')
# Or initialize with config dictscs=SCS({
'api_key': 'your-api-key',
'project_id': 'your-project-id',
'base_url': 'https://your-scs-instance.com'
})
# Authenticationuser=scs.auth.login(email='user@example.com', password='password123')
# Databaseusers=scs.database.collection('users').where('age', '>=', 18).limit(10).get()
# Storagescs.storage.upload('./image.png', folder='images')# Register a new useruser=scs.auth.register(
email='user@example.com',
password='password123',
display_name='John Doe'
)
# Loginuser=scs.auth.login(email='user@example.com', password='password123')
# Get current userme=scs.auth.get_current_user()
# Update profilescs.auth.update_profile(display_name='Jane Doe')
# Change passwordscs.auth.change_password(
current_password='old123',
new_password='new456'
)
# Logoutscs.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 Googleuser=scs.auth.sign_in_with_google(
id_token='google-id-token', # Required: ID token from Google Sign-Inaccess_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:
fromgoogle.oauth2importid_tokenfromgoogle.auth.transportimportrequests# Verify and get token on server sidedefverify_google_token(token):
try:
idinfo=id_token.verify_oauth2_token(
token, requests.Request(), GOOGLE_CLIENT_ID
)
returnidinfoexceptValueError:
returnNone# Sign in with the tokenuser=scs.auth.sign_in_with_google(id_token=google_token)Authenticate users with their Facebook account.
# Sign in with Facebookuser=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 clientdeffacebook_login(access_token):
try:
user=scs.auth.sign_in_with_facebook(access_token=access_token)
returnuserexceptExceptionase:
print(f"Facebook login failed: {e}")
returnNoneAuthenticate users with their Apple ID. Ideal for iOS apps and required for apps with social login on the App Store.
# Sign in with Appleuser=scs.auth.sign_in_with_apple(
identity_token='apple-identity-token', # Required: Identity token from Sign in with Appleauthorization_code='apple-auth-code', # Optional: Authorization code for server verificationfull_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 GitHubuser=scs.auth.sign_in_with_github(
code='github-oauth-code', # Required: OAuth authorization coderedirect_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):
fromflaskimportFlask, redirect, requestimportrequestsapp=Flask(__name__)
GITHUB_CLIENT_ID='your-client-id'GITHUB_CLIENT_SECRET='your-client-secret'@app.route('/login/github')defgithub_login():
returnredirect(
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')defgithub_callback():
code=request.args.get('code')
ifcode:
user=scs.auth.sign_in_with_github(
code=code,
redirect_uri='https://yourapp.com/callback'
)
returnf"Welcome, {user['displayName']}!"return"Login failed"Authenticate users with their Twitter/X account using OAuth 1.0a.
# Sign in with Twitter/Xuser=scs.auth.sign_in_with_twitter(
oauth_token='twitter-oauth-token', # Required: OAuth tokenoauth_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 Microsoftuser=scs.auth.sign_in_with_microsoft(
access_token='microsoft-access-token', # Required: Access token from MSALid_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:
frommsalimportConfidentialClientApplicationapp=ConfidentialClientApplication(
client_id="your-client-id",
authority="https://login.microsoftonline.com/common",
client_credential="your-client-secret"
)
# After getting tokens from authorization code flowresult=app.acquire_token_by_authorization_code(
code,
scopes=["User.Read"],
redirect_uri="https://yourapp.com/callback"
)
if"access_token"inresult:
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 providertry:
user=scs.auth.link_provider('google', {
'idToken': 'google-id-token'
})
print("Account upgraded! User data preserved.")
print(f"Is anonymous: {user['isAnonymous']}") # FalseexceptExceptionase:
if'credential-already-in-use'instr(e):
# This Google account is already linked to another userprint("This account is already registered. Please sign in instead.")
else:
raiseTwo-step authentication flow using SMS verification codes.
# Step 1: Send verification code to phoneresult=scs.auth.send_phone_verification_code(
phone_number='+1234567890', # Required: E.164 formatrecaptcha_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 receiveduser=scs.auth.sign_in_with_phone_number(
verification_id=verification_id, # The ID from step 1code='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:
defsign_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 coderesult=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 codeuser=scs.auth.sign_in_with_phone_number(
verification_id=verification_id,
code=code
)
returnuserexceptExceptionase:
error_msg=str(e).lower()
if'invalid-phone-number'inerror_msg:
raiseValueError('Invalid phone number format. Use E.164 format (+1234567890)')
elif'too-many-requests'inerror_msg:
raiseValueError('Too many attempts. Please try again later.')
elif'invalid-verification-code'inerror_msg:
raiseValueError('Invalid verification code. Please try again.')
elif'code-expired'inerror_msg:
raiseValueError('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:
importjwtimporttimeimportosdefcreate_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': claimsor {},
'iat': int(time.time()),
'exp': int(time.time()) +3600# 1 hour
}
returnjwt.encode(
payload,
os.environ['SCS_SECRET_KEY'],
algorithm='HS256'
)
# Generate token for a usercustom_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 accountuser=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 accountuser=scs.auth.unlink_provider('facebook')
print(f"Remaining providers: {user['providerData']}")
# Get available sign-in methods for an emailresult=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:
defcan_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', [])
ifproviderinmethods:
raiseValueError(f"{provider} is already linked to this account")
returnTruedeflink_google_account(google_id_token: str) ->dict:
"""Link Google to the current user's account."""try:
# Verify user is signed incurrent_user=scs.auth.get_current_user()
ifnotcurrent_user:
raiseValueError('Must be signed in to link accounts')
# Link the provideruser=scs.auth.link_provider('google', {
'idToken': google_id_token
})
print('Successfully linked Google account')
returnuserexceptExceptionase:
error_msg=str(e).lower()
if'credential-already-in-use'inerror_msg:
print('This Google account is already linked to another user')
elif'provider-already-linked'inerror_msg:
print('Google is already linked to this account')
raiseHandle password recovery and email verification flows.
# Send password reset emailscs.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 linknew_password='newSecurePassword123'# User's new password
)
print("Password successfully reset")
# Send email verification to current userscs.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:
defreset_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'}
exceptExceptionase:
error_msg=str(e).lower()
if'user-not-found'inerror_msg:
# Don't reveal if user exists for securityreturn {'success': True, 'message': 'If this email exists, a reset link was sent'}
elif'too-many-requests'inerror_msg:
return {'success': False, 'message': 'Too many attempts. Please try later.'}
else:
raisedefconfirm_reset(code: str, new_password: str) ->dict:
"""Confirm password reset with validation."""# Validate password strengthiflen(new_password) <8:
raiseValueError('Password must be at least 8 characters')
try:
scs.auth.confirm_password_reset(code=code, new_password=new_password)
return {'success': True}
exceptExceptionase:
error_msg=str(e).lower()
if'expired-action-code'inerror_msg:
return {'success': False, 'message': 'Reset link expired. Please request a new one.'}
elif'invalid-action-code'inerror_msg:
return {'success': False, 'message': 'Invalid reset link.'}
elif'weak-password'inerror_msg:
return {'success': False, 'message': 'Password is too weak.'}
else:
raiseManage user sessions and authentication state.
# Check if user is logged inis_logged_in=scs.auth.is_logged_inprint(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 datarefreshed_user=scs.auth.reload()
# Get the current auth tokentoken=scs.auth.tokenfromscsimportSCS, AuthenticationErrorclassAuthService:
def__init__(self):
self.scs=SCS({
'api_key': 'your-api-key',
'project_id': 'your-project-id',
'base_url': 'https://your-scs-instance.com'
})
defregister(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 emailself.scs.auth.send_email_verification()
returnuserdeflogin(self, email: str, password: str) ->dict:
"""Login with email and password."""returnself.scs.auth.login(email=email, password=password)
defsocial_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)
}
ifprovidernotinmethods:
raiseValueError(f"Unknown provider: {provider}")
returnmethods[provider]()
defcontinue_as_guest(self, custom_data: dict=None) ->dict:
"""Sign in anonymously for guest access."""returnself.scs.auth.sign_in_anonymously(custom_data=custom_dataor {})
defupgrade_guest_account(self, provider: str, credentials: dict) ->dict:
"""Upgrade anonymous account to permanent."""user=self.scs.auth.get_current_user()
ifnotuserornotuser.get('isAnonymous'):
raiseValueError('Current user is not anonymous')
returnself.scs.auth.link_provider(provider, credentials)
deflogout(self):
"""Sign out the current user."""self.scs.auth.logout()
# Usageauth=AuthService()
# Register new useruser=auth.register('user@example.com', 'password123', 'John Doe')
# Or sign in with Googlegoogle_user=auth.social_login('google', {'id_token': 'xxx'})
# Or continue as guest and upgrade laterguest=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 |
fromscsimportSCS# eaZI is the default database - no special configuration neededscs=SCS({
'project_id': 'your-project-id',
'api_key': 'your-api-key'# database_type: 'eazi' is implicit
})fromscsimportSCS# Use RelaDB for productionscs=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 referenceusers=scs.database.collection('users')
# List all collectionscollections=scs.database.list_collections()
# Create a collectionscs.database.create_collection('new_collection')
# Delete a collectionscs.database.delete_collection('old_collection')# Add document with auto-generated IDdoc=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 documentuser=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 documentscs.database.collection('users').doc('user-123').delete()# Simple query with single filteractive_users=scs.database.collection('users') \
.where('status', '==', 'active') \
.get()
# Multiple filtersresults=scs.database.collection('users') \
.where('age', '>=', 18) \
.where('status', '==', 'active') \
.get()
# Ordering and paginationposts=scs.database.collection('posts') \
.where('published', '==', True) \
.order_by('created_at', 'desc') \
.limit(10) \
.skip(20) \
.get()
# Using 'in' operatorfeatured=scs.database.collection('posts') \
.where('category', 'in', ['tech', 'science', 'news']) \
.get()
# Using 'contains' for array fieldstagged=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 subcollectionposts_ref=scs.database \
.collection('users') \
.doc('user_id') \
.collection('posts')
# Add to subcollectionpost=posts_ref.add({
'title': 'My First Post',
'content': 'Hello World!',
'created_at': datetime.now().isoformat()
})
# Query subcollectionuser_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 pathfile_info=scs.storage.upload('./image.png')
# Upload with folderfile_info=scs.storage.upload('./doc.pdf', folder='documents')
# Upload from bytesfile_info=scs.storage.upload_bytes(
data=image_bytes,
filename='image.png',
content_type='image/png'
)
# List filesfiles=scs.storage.list_files(folder='images')
# Get file referencefile_ref=scs.storage.ref('file-id')
# Download filecontent=file_ref.download()
# Download to filefile_ref.download_to_file('./local_file.png')
# Get metadatametadata=file_ref.get_metadata()
# Delete filefile_ref.delete()
# Folder operationsscs.storage.create_folder('my-folder')
scs.storage.delete_folder('my-folder')Real-time data synchronization via WebSocket:
# Connect to realtime servicescs.realtime.connect()
# Get referencechat_ref=scs.realtime.ref('chat/room1')
# Subscribe to updatesdefon_message(data, event):
print(f'Event: {event}, Data: {data}')
unsubscribe=chat_ref.on(on_message)
# Subscribe to single updatechat_ref.once(lambdadata, event: print(data))
# Unsubscribeunsubscribe()
# Disconnectscs.realtime.disconnect()Push notifications with topics and direct messaging:
# Register device tokenscs.messaging.register_token(
token='device-fcm-token',
platform='android'
)
# Topic operationsscs.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 topicscs.messaging.send_to_topic(
topic='news',
title='Breaking News',
body='Something happened!',
data={'articleId': '123'}
)
# Send to specific devicescs.messaging.send_to_token(
token='device-token',
title='Personal Alert',
body='You have a new message'
)
# Send to multiple devicesscs.messaging.send_to_tokens(
tokens=['token1', 'token2'],
title='Broadcast',
body='Hello everyone!'
)Dynamic app configuration:
# Fetch configurationconfig=scs.remote_config.fetch()
# Get values with type safetytheme=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 parametersscs.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 changesscs.remote_config.publish()
# Version managementversions=scs.remote_config.list_versions()
scs.remote_config.rollback('version-id')Execute custom code on the backend:
# Invoke a functionresult=scs.functions.invoke('processOrder', {
'orderId': '12345',
'action': 'confirm'
})
# Admin: Create a functionscs.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 functionsfunctions=scs.functions.list()
# Admin: Update functionscs.functions.update('function-id', code='...')
# Admin: Test functionresult=scs.functions.test('function-id', {'test': 'data'})
# Admin: Get logslogs=scs.functions.get_logs('function-id')Chat, text completion, and image generation with local LLM models:
# Chat with AIresponse=scs.ai.chat(
message="What is the capital of France?",
system_prompt="You are a helpful geography assistant."
)
print(response['content'])
# Text completionresponse=scs.ai.complete(prompt="Once upon a time")
print(response['content'])
# Generate imageresponse=scs.ai.generate_image(prompt="A sunset over mountains")
print(response['imageUrl'])
# List available modelsmodels=scs.ai.list_models()
# Conversation managementconversation=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 agentagent=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 agentsagents=scs.ai.list_agents()
# Run the agentresponse=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 sessionresponse=scs.ai.run_agent(
agent_id=agent['agentId'],
input="Thanks! What about enabling 2FA?",
session_id=response['sessionId']
)
# List agent sessionssessions=scs.ai.list_agent_sessions(agent['agentId'])
# Get full session historysession=scs.ai.get_agent_session(agent['agentId'], response['sessionId'])
formsginsession['messages']:
print(f"{msg['role']}: {msg['content']}")
# Update agentscs.ai.update_agent(
agent_id=agent['agentId'],
instructions="Updated instructions here",
temperature=0.5
)
# Define a tool for agentstool=scs.ai.define_tool(
name="get_weather",
description="Get weather for a location",
parameters={
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
}
}
)
# List toolstools=scs.ai.list_tools()
# Delete agent and sessionsscs.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"
}
}fromscsimportSCS, SCSError, AuthenticationError, NotFoundError, ValidationErrortry:
user=scs.auth.login(email='user@example.com', password='wrong')
exceptAuthenticationErrorase:
print(f'Auth failed: {e.message}')
print(f'Status: {e.status}')
exceptNotFoundErrorase:
print(f'Not found: {e.message}')
exceptValidationErrorase:
print(f'Validation error: {e.message}')
exceptSCSErrorase:
print(f'SCS error: {e.message}')withSCS({'api_key': '...', 'project_id': '...'}) asscs:
users=scs.database.collection('users').get()
# Connection automatically closed- Python 3.8+
- requests
- python-socketio[client] (optional, for realtime functionality)
MIT License