Python API Reference¶
This page provides comprehensive documentation for all SFAI Python API functions, including parameters, return values, and usage examples.
sfai.app
- Application Management¶
init
¶
Initialize a new SFAI application.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
app_name | Optional[str] | Name of the application (defaults to directory name) | None |
template | str | Template to use for scaffolding (eg: fastapi_hello or flask_hello) | 'fastapi_hello' |
force | bool | Whether to force reinitialization if already initialized | False |
Returns:
Type | Description |
---|---|
Dict[str, Any] | Dictionary with initialization status and details |
Source code in sfai/app/init.py
def init(
app_name: Optional[str] = None, template: str = "fastapi_hello", force: bool = False
) -> Dict[str, Any]:
"""
Initialize a new SFAI application.
Args:
app_name: Name of the application (defaults to directory name)
template: Template to use for scaffolding (eg: fastapi_hello or flask_hello)
force: Whether to force reinitialization if already initialized
Returns:
Dictionary with initialization status and details
"""
# Use current directory as target path
target_path = Path.cwd()
# Determine app name (use directory name if not provided)
app_name = app_name or target_path.name
# Check if already initialized
context_file = target_path / CONTEXT_DIR / CONTEXT_FILE.name
context_exists = context_file.exists()
if context_exists and not force:
return BaseResponse(
success=False,
error=(
f"App '{app_name}' is already initialized. "
f"Use force=True to reinitialize."
),
app_name=app_name,
)
try:
# Initialize the app with the specified template
scaffold_hello_app(target_path, force, template)
# Update environment and register app
ctx_mgr = ContextManager()
ctx_mgr.update_platform(
platform="local",
environment="default",
app_name=app_name,
values={"app_name": app_name},
)
ctx_mgr.register_app(app_name, str(target_path))
return BaseResponse(
success=True,
app_name=app_name,
message=(
f"App '{app_name}' initialized successfully with template '{template}'"
),
)
except (ValueError, Exception) as e:
return BaseResponse(success=False, error=f"Failed to initialize app: {e!s}")
Examples:
from sfai.app import init
# Initialize with default template
result = init()
# Initialize with specific template
result = init(app_name="my-api", template="fastapi_hello")
# Force reinitialize existing app
result = init(force=True, template="flask_hello")
deploy
¶
Deploy an application to the configured environment.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path | str | Path to the application directory | '.' |
platform | Optional[str] | Platform to deploy to | None |
environment | Optional[str] | Environment to deploy to (uses active environment if None) | None |
kwargs | Any | Additional keyword arguments | {} |
Returns:
Type | Description |
---|---|
BaseResponse | Dictionary with deployment status and details |
Source code in sfai/app/deploy.py
def deploy(
path: str = ".",
platform: Optional[str] = None,
environment: Optional[str] = None,
**kwargs: Any,
) -> BaseResponse:
"""
Deploy an application to the configured environment.
Args:
path: Path to the application directory
platform: Platform to deploy to
environment: Environment to deploy to (uses active environment if None)
kwargs: Additional keyword arguments
Returns:
Dictionary with deployment status and details
"""
try:
ctx_mgr = ContextManager()
# determine the platform and environment to use
response = determine_platform_and_environment(platform, environment)
if not response.success:
return response
active_platform = response.platform
active_environment = response.environment
# Read the updated context for the determined platform and environment
context = ctx_mgr.read_context(active_platform, active_environment)
if not context:
return BaseResponse(
success=False,
error=(
f"Failed to read context for platform '{active_platform}' "
f"and environment '{active_environment}'"
),
)
provider = PLATFORM_REGISTRY.get(active_platform)
if not provider:
return BaseResponse(
success=False, error=f"Unsupported provider: {active_platform}"
)
result = provider.deploy(context=context, path=path, **kwargs)
return result.with_update(
app_name=context.get("app_name"),
platform=active_platform,
environment=active_environment,
)
except ValueError as e:
return BaseResponse(success=False, error=f"Context validation error: {e!s}")
Examples:
from sfai.app import deploy
# Deploy to current platform
result = deploy()
# Deploy to specific platform
result = deploy(platform="heroku")
# Deploy from specific directory
result = deploy(path="./my-app")
# Deploy with additional parameters
result = deploy(platform="heroku", commit_message="Feature: Add new API endpoint")
open
¶
Open the current app in the browser.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
path | str | The path to open | '/docs' |
port | int | The port to open | 8080 |
tunnel | bool | Whether to use a tunnel | False |
url | str | None | The URL to open | None |
platform | Optional[str] | Platform to open from (optional) | None |
environment | Optional[str] | Environment to open from (defaults to "default") | None |
Returns: A dictionary containing the result of the open operation
Source code in sfai/app/open.py
def open(
path: str = "/docs",
port: int = 8080,
tunnel: bool = False,
url: str | None = None,
platform: Optional[str] = None,
environment: Optional[str] = None,
) -> BaseResponse:
"""
Open the current app in the browser.
Args:
path: The path to open
port: The port to open
tunnel: Whether to use a tunnel
url: The URL to open
platform: Platform to open from (optional)
environment: Environment to open from (defaults to "default")
Returns:
A dictionary containing the result of the open operation
"""
try:
# Load current context
ctx_mgr = ContextManager()
# Determine the platform and environment to use
response = determine_platform_and_environment(platform, environment)
if not response.success:
return response
# Validate platform provider
active_platform = response.platform
active_environment = response.environment
# Read the updated context for the determined platform and environment
context = ctx_mgr.read_context(active_platform, active_environment)
if not context:
return BaseResponse(
success=False,
error=(
f"Failed to read context for platform '{active_platform}' "
f"and environment '{active_environment}'"
),
)
provider = PLATFORM_REGISTRY.get(active_platform)
if not provider:
return BaseResponse(
success=False, error=f"Unsupported provider: {active_platform}"
)
# Validate tunnel requirements
if tunnel and active_platform != "local":
return BaseResponse(
success=False,
error="Tunneling is only supported in local environment.",
)
# Execute the open operation
result = provider.open(context=context, path=path, url=url)
# Return result with context metadata
return result.with_update(
app_name=context.get("app_name"),
platform=active_platform,
environment=active_environment,
)
except ValueError as e:
return BaseResponse(success=False, error=f"Context validation error: {e!s}")
Examples:
from sfai.app import open
# Open app with default settings
result = open()
# Open specific path
result = open(path="/api/v1/health")
# Open with tunnel for public access
result = open(tunnel=True)
# Open on custom port
result = open(port=3000)
# Open custom URL
result = open(url="https://my-app.herokuapp.com")
status
¶
Show the status of the current app from context.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
platform | Optional[str] | Platform to get status from (optional) | None |
environment | Optional[str] | Environment to get status from (uses active environment if None) | None |
Source code in sfai/app/status.py
def status(
platform: Optional[str] = None, environment: Optional[str] = None
) -> BaseResponse:
"""
Show the status of the current app from context.
Args:
platform: Platform to get status from (optional)
environment: Environment to get status from (uses active environment if None)
"""
try:
ctx_mgr = ContextManager()
# determine the platform and environment to use
response = determine_platform_and_environment(platform, environment)
if not response.success:
return response
active_platform = response.platform
active_environment = response.environment
# Read the updated context for the determined platform and environment
context = ctx_mgr.read_context(active_platform, active_environment)
if not context:
return BaseResponse(
success=False,
error=(
f"Failed to read context for platform '{active_platform}' "
f"and environment '{active_environment}'"
),
)
provider = PLATFORM_REGISTRY.get(active_platform)
if not provider:
return BaseResponse(
success=False, error=f"Unsupported provider: {active_platform}"
)
status_response = provider.status(context=context)
return status_response.with_update(
app_name=context.get("app_name"),
platform=active_platform,
environment=active_environment,
)
except ValueError as e:
return BaseResponse(success=False, error=f"Context validation error: {e!s}")
Examples:
from sfai.app import status
# Show status from current platform
result = status()
# Show status from specific platform
result = status(platform="heroku")
logs
¶
Show logs for the current app.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
platform | Optional[str] | Platform to show logs for | None |
environment | Optional[str] | Environment to show logs for (uses active environment if None) | None |
Returns:
Name | Type | Description |
---|---|---|
BaseResponse | BaseResponse | Response object containing logs |
Source code in sfai/app/logs.py
def logs(
platform: Optional[str] = None, environment: Optional[str] = None
) -> BaseResponse:
"""
Show logs for the current app.
Args:
platform: Platform to show logs for
environment: Environment to show logs for (uses active environment if None)
Returns:
BaseResponse: Response object containing logs
"""
try:
ctx_mgr = ContextManager()
# Determine which platform and environment to use
response = determine_platform_and_environment(platform, environment)
if not response.success:
return response
active_platform = response.platform
active_environment = response.environment
# Read the updated context for the determined platform and environment
context = ctx_mgr.read_context(active_platform, active_environment)
if not context:
return BaseResponse(
success=False,
error=(
f"Failed to read context for platform '{active_platform}' "
f"and environment '{active_environment}'"
),
)
provider = PLATFORM_REGISTRY.get(active_platform)
if not provider:
return BaseResponse(
success=False, error=f"Unsupported provider: {active_platform}"
)
logs_response = provider.logs(context=context)
return logs_response.with_update(
app_name=context.get("app_name"),
platform=active_platform,
environment=active_environment,
)
except ValueError as e:
return BaseResponse(success=False, error=f"Context validation error: {e!s}")
Examples:
from sfai.app import logs
# Show logs from current platform
result = logs()
# Show logs from specific platform
result = logs(platform="eks")
delete
¶
Delete the current app from the context.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
platform | Optional[str] | Platform to delete from (optional) | None |
environment | Optional[str] | Environment to delete from (uses active environment if None) | None |
Source code in sfai/app/delete.py
def delete(
platform: Optional[str] = None, environment: Optional[str] = None
) -> BaseResponse:
"""
Delete the current app from the context.
Args:
platform: Platform to delete from (optional)
environment: Environment to delete from (uses active environment if None)
"""
try:
ctx_mgr = ContextManager()
# determine the platform and environment to use
response = determine_platform_and_environment(platform, environment)
if not response.success:
return response
active_platform = response.platform
active_environment = response.environment
# Read the updated context for the determined platform and environment
context = ctx_mgr.read_context(active_platform, active_environment)
if not context:
return BaseResponse(
success=False,
error=(
f"Failed to read context for platform '{active_platform}' "
f"and environment '{active_environment}'"
),
)
provider = PLATFORM_REGISTRY.get(active_platform)
if not provider:
return BaseResponse(
success=False, error=f"Unsupported provider: {active_platform}"
)
delete_response = provider.delete(context=context)
return delete_response.with_update(
app_name=context.get("app_name"),
platform=active_platform,
environment=active_environment,
)
except ValueError as e:
return BaseResponse(success=False, error=f"Context validation error: {e!s}")
Examples:
from sfai.app import delete
# Delete from current platform
result = delete()
# Delete from specific platform
result = delete(platform="heroku")
Source code in sfai/app/context.py
def get_context() -> BaseResponse:
try:
context = ctx_mgr.read_context()
if not context:
return BaseResponse(
success=False,
app_name=None,
error="No app context found",
)
return BaseResponse(
success=True,
app_name=context.get("app_name"),
platform=context.get("active_platform"),
environment=context.get("active_environment"),
context=context,
)
except ValueError as e:
return BaseResponse(
success=False,
app_name=None,
error=str(e),
)
Examples:
from sfai.app import get_context
# Get current context
result = get_context()
if result.success:
print(f"App: {result.app_name}")
print(f"Platform: {result.platform}")
Delete the current context
Source code in sfai/app/context.py
def delete_context() -> BaseResponse:
"""
Delete the current context
"""
try:
context = ctx_mgr.read_context()
if not context:
return BaseResponse(
success=False,
app_name=None,
error="No app context found",
)
app_name = context.get("app_name")
if CONTEXT_FILE.exists():
CONTEXT_FILE.unlink()
ctx_mgr.unregister_app(app_name)
return BaseResponse(
success=True,
app_name=app_name,
message=f"Context for {app_name} deleted and unregistered",
)
else:
return BaseResponse(
success=False,
app_name=app_name,
error=f"Context for {app_name} not found",
)
except ValueError as e:
return BaseResponse(
success=False,
app_name=app_name,
error=str(e),
)
Examples:
Examples:
from sfai.app import publish
# Publish to MuleSoft with specific parameters
result = publish(
service="mulesoft",
profile="production",
endpoint_uri="https://api.example.com",
gateway_id="abc123",
gateway_version="1.0.0"
)
# Publish with tags
result = publish(
service="mulesoft",
name="my-api",
tags=["api", "production", "v1"]
)
Source code in sfai/app/helm.py
def download_helm_chart() -> BaseResponse:
try:
ctx_mgr = ContextManager()
context = ctx_mgr.read_context()
if not context:
return BaseResponse(
success=False,
app_name=None,
error="No app context found",
)
chart_path = CHARTS_PATH
if not chart_path.exists():
return BaseResponse(
success=False,
error="Helm chart not found",
)
# Download the chart
destination_path = Path("./helm-chart")
if destination_path.exists():
shutil.rmtree(destination_path)
shutil.copytree(chart_path, destination_path)
# Show warning about local chart usage
console.print(
f"{WARNING_EMOJI} [{WARNING_COLOR}]Custom helm chart found. This "
f"chart folder will be used for future deployments. Delete "
f"./helm-chart to use the default chart.[/]"
)
return BaseResponse(
success=True,
message="Helm chart downloaded successfully",
app_name=context.get("app_name"),
platform=context.get("platform"),
)
except ValueError as e:
return BaseResponse(success=False, error=f"Context validation error: {e!s}")
Examples:
from sfai.app import download_helm_chart
# Download Helm chart for current app
result = download_helm_chart()
sfai.config
- Service Configuration¶
init
¶
Initialize configuration for a service.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
service | str | Service name (e.g., "mulesoft") | required |
credentials | Dictionary of credentials for the service | required | |
profile_name | str | Profile name to store credentials under | 'default' |
env | Optional[str] | Environment to set as active (uses current if None) | None |
**kwargs | pass values directly to the service provider | {} |
Returns:
Type | Description |
---|---|
BaseResponse | BaseResponse |
Source code in sfai/config/init.py
def init(
service: str,
config: Optional[Dict[str, Any]] = None,
profile_name: str = "default",
env: Optional[str] = None,
**kwargs,
) -> BaseResponse:
"""
Initialize configuration for a service.
Args:
service: Service name (e.g., "mulesoft")
credentials: Dictionary of credentials for the service
profile_name: Profile name to store credentials under
env: Environment to set as active (uses current if None)
**kwargs: pass values directly to the service provider
Returns:
BaseResponse
"""
ctx_mgr = ContextManager()
# Read current context to get app info if needed
context = ctx_mgr.read_context()
if not context:
return BaseResponse(
success=False, error="No app context found. Initialize an app first."
)
app_name = context.get("app_name")
current_platform = env or context.get("active_platform")
if config is None and not kwargs:
return BaseResponse(success=False, error="No configuration provided.")
config = config or kwargs
if not app_name or not current_platform:
return BaseResponse(
success=False, error="App name or platform missing in context."
)
# Validate credentials
result = validate(service, config)
if not result.success:
return result.with_update(
service=service,
profile_name=profile_name,
)
try:
# Save the service profile
ctx_mgr.add_service_profile(service, profile_name, config)
# Update the environment to use this profile
ctx_mgr.update_platform(current_platform, {service: {"profile": profile_name}})
return BaseResponse(
success=True,
service=service,
profile_name=profile_name,
)
except ValueError as e:
return BaseResponse(success=False, error=f"Failed to save credentials: {e!s}")
Examples:
from sfai.config import init
# Initialize MuleSoft configuration
result = init(
service="mulesoft",
profile_name="production",
org_id="abc123",
environment_id="def456",
client_id="ghi789",
client_secret="secret123"
)
# Initialize with config dictionary
config = {
"org_id": "abc123",
"client_id": "ghi789",
"client_secret": "secret123"
}
result = init(service="mulesoft", config=config)
update
¶
Update configuration for a service.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
service | str | Service name | required |
updates | Dict[str, Any] | New values to update | required |
profile_name | str | Profile name to update | 'default' |
Returns:
Type | Description |
---|---|
BaseResponse | BaseResponse |
Source code in sfai/config/update.py
def update(
service: str, updates: Dict[str, Any], profile_name: str = "default"
) -> BaseResponse:
"""
Update configuration for a service.
Args:
service: Service name
updates: New values to update
profile_name: Profile name to update
Returns:
BaseResponse
"""
ctx_mgr = ContextManager()
# Check if service and profile are valid
result = profile_exists(service, profile_name)
if not result.success:
return result.with_update(
service=service,
profile_name=profile_name,
)
try:
ctx_mgr.update_service_profile(service, profile_name, updates)
return BaseResponse(
success=True,
service=service,
profile_name=profile_name,
updated_fields=list(updates.keys()),
)
except ValueError as e:
return BaseResponse(
success=False, error=f"Failed to update configuration: {e!s}"
)
Examples:
from sfai.config import update
# Update specific fields
result = update(
service="mulesoft",
profile_name="production",
updates={"client_secret": "new-secret"}
)
# Update multiple fields
result = update(
service="mulesoft",
updates={
"org_id": "new-org",
"environment_id": "new-env"
}
)
list
¶
List all profiles for one or all services.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
service | Optional[str] | Service name, or None to list all services | None |
Returns:
Type | Description |
---|---|
BaseResponse | BaseResponse with operation result and profiles list |
Source code in sfai/config/list.py
def list(service: Optional[str] = None) -> BaseResponse:
"""
List all profiles for one or all services.
Args:
service: Service name, or None to list all services
Returns:
BaseResponse with operation result and profiles list
"""
ctx_mgr = ContextManager()
try:
if service:
# Use the ContextManager method for single service
profiles = ctx_mgr.list_service_profiles(service)
if not profiles:
return BaseResponse(
success=False, error=f"No profiles found for service: {service}"
)
return BaseResponse(success=True, service=service, profiles=profiles)
else:
# Get all services and their profiles
context = ctx_mgr._load_json(ctx_mgr.global_context_file)
all_profiles = context.get("service_profiles", {})
if not all_profiles:
return BaseResponse(success=True, profiles={})
result = {}
for svc in all_profiles.keys():
result[svc] = ctx_mgr.list_service_profiles(svc)
return BaseResponse(success=True, profiles=result)
except Exception as e:
return BaseResponse(success=False, error=f"Failed to list profiles: {e!s}")
Examples:
from sfai.config import list
# List all profiles
result = list()
# List profiles for specific service
result = list(service="mulesoft")
view
¶
View details of a service profile.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
service | str | Service name | required |
profile_name | str | Profile name to view | 'default' |
Returns:
Type | Description |
---|---|
BaseResponse | BaseResponse |
Source code in sfai/config/view.py
def view(service: str, profile_name: str = "default") -> BaseResponse:
"""
View details of a service profile.
Args:
service: Service name
profile_name: Profile name to view
Returns:
BaseResponse
"""
ctx_mgr = ContextManager()
# Check if profile exists
exists, error = profile_exists(service, profile_name)
if not exists:
return BaseResponse(
success=False,
error=error,
service=service,
profile_name=profile_name,
)
# Get the profile
profile = ctx_mgr.get_service_profile(service, profile_name)
# Create a safe version with masked secrets
safe_profile = {}
for key, value in profile.items():
if any(s in key.lower() for s in ["secret", "password", "key"]):
# Mask the secret value, showing just the first and last character
safe_profile[key] = (
f"{value[0]}{'*' * (len(str(value)) - 2)}{value[-1]}"
if len(str(value)) > 4
else "****"
)
else:
safe_profile[key] = value
return BaseResponse(
success=True,
message=f"Profile '{profile_name}' for service '{service}' is shown below",
profile_name=profile_name,
service=service,
data=safe_profile,
)
Examples:
from sfai.config import view
# View default profile
result = view(service="mulesoft")
# View specific profile
result = view(service="mulesoft", profile_name="production")
delete
¶
Delete a service profile.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
service | str | Service name | required |
profile_name | str | Profile name to delete | 'default' |
Returns:
Type | Description |
---|---|
BaseResponse | BaseResponse |
Source code in sfai/config/delete.py
def delete(service: str, profile_name: str = "default") -> BaseResponse:
"""
Delete a service profile.
Args:
service: Service name
profile_name: Profile name to delete
Returns:
BaseResponse
"""
ctx_mgr = ContextManager()
# Check if profile exists
exists, error = profile_exists(service, profile_name)
if not exists:
return BaseResponse(success=False, error=error)
try:
# Delete the profile
ctx_mgr.delete_service_profile(service, profile_name)
# Check if this profile is referenced in any environments
context = ctx_mgr._load_json(ctx_mgr.context_file)
environments = context.get("environments", {})
# For each environment, check if it uses this profile
for env_name, env_data in environments.items():
if service in env_data and env_data[service].get("profile") == profile_name:
# Remove the profile reference from this environment
ctx_mgr.clear_platform_keys(env_name, [service])
return BaseResponse(
success=True,
service=service,
profile_name=profile_name,
message=(
f"Profile '{profile_name}' for service '{service}' has been deleted."
),
)
except Exception as e:
return BaseResponse(success=False, error=f"Failed to delete profile: {e!s}")
Examples:
from sfai.config import delete
# Delete default profile
result = delete(service="mulesoft")
# Delete specific profile
result = delete(service="mulesoft", profile_name="production")
sfai.core
- Core Models¶
BaseResponse
¶
Standard response model for all API calls.
Attributes: - success
(bool): Operation success status - message
(str): Human-readable message - error
(Optional[str]): Error message if success=False - Additional fields specific to each operation
Methods: - with_update(**kwargs)
: Create a new response with additional fields
Example: