Initial commit
This commit is contained in:
139
skills/phenoml-workflow/scripts/check_env.py
Executable file
139
skills/phenoml-workflow/scripts/check_env.py
Executable file
@@ -0,0 +1,139 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Environment Variables Checker
|
||||
|
||||
Safely checks which environment variables are set without exposing their values.
|
||||
This prevents accidental credential leakage in LLM conversations.
|
||||
|
||||
Usage:
|
||||
python3 check_env.py
|
||||
python3 check_env.py --help
|
||||
|
||||
Security: This script only reports presence (true/false), never actual values.
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from dotenv import load_dotenv
|
||||
|
||||
def check_env_vars():
|
||||
"""Check presence of required environment variables without exposing values"""
|
||||
load_dotenv()
|
||||
|
||||
# Core credentials (always required)
|
||||
core_vars = {
|
||||
"PHENOML_USERNAME": bool(os.getenv("PHENOML_USERNAME")),
|
||||
"PHENOML_PASSWORD": bool(os.getenv("PHENOML_PASSWORD")),
|
||||
"PHENOML_BASE_URL": bool(os.getenv("PHENOML_BASE_URL"))
|
||||
}
|
||||
|
||||
# FHIR provider credentials (required for setup)
|
||||
fhir_credentials = {
|
||||
"FHIR_PROVIDER_BASE_URL": bool(os.getenv("FHIR_PROVIDER_BASE_URL")),
|
||||
"FHIR_PROVIDER_CLIENT_ID": bool(os.getenv("FHIR_PROVIDER_CLIENT_ID")),
|
||||
"FHIR_PROVIDER_CLIENT_SECRET": bool(os.getenv("FHIR_PROVIDER_CLIENT_SECRET"))
|
||||
}
|
||||
|
||||
# Generated IDs (created by scripts)
|
||||
generated_ids = {
|
||||
"FHIR_PROVIDER_ID": bool(os.getenv("FHIR_PROVIDER_ID")),
|
||||
"WORKFLOW_ID": bool(os.getenv("WORKFLOW_ID"))
|
||||
}
|
||||
|
||||
return {
|
||||
"core_credentials": core_vars,
|
||||
"fhir_credentials": fhir_credentials,
|
||||
"generated_ids": generated_ids
|
||||
}
|
||||
|
||||
def print_status(status, verbose=False):
|
||||
"""Print status in a user-friendly format"""
|
||||
|
||||
def check_mark(present):
|
||||
return "✅" if present else "❌"
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("ENVIRONMENT VARIABLES STATUS")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
# Core credentials
|
||||
print("Core PhenoML Credentials:")
|
||||
for key, present in status["core_credentials"].items():
|
||||
print(f" {check_mark(present)} {key}")
|
||||
|
||||
core_ready = all(status["core_credentials"].values())
|
||||
if not core_ready:
|
||||
print("\n⚠️ Missing core credentials. Add them to .env file:")
|
||||
print(" PHENOML_USERNAME=your_username")
|
||||
print(" PHENOML_PASSWORD=your_password")
|
||||
print(" PHENOML_BASE_URL=your_base_url")
|
||||
|
||||
# FHIR credentials
|
||||
print("\nFHIR Provider Credentials:")
|
||||
for key, present in status["fhir_credentials"].items():
|
||||
print(f" {check_mark(present)} {key}")
|
||||
|
||||
fhir_ready = all(status["fhir_credentials"].values())
|
||||
if not fhir_ready:
|
||||
print("\n⚠️ Missing FHIR credentials. Add them to .env file:")
|
||||
print(" FHIR_PROVIDER_BASE_URL=https://api.medplum.com/fhir/R4")
|
||||
print(" FHIR_PROVIDER_CLIENT_ID=your_client_id")
|
||||
print(" FHIR_PROVIDER_CLIENT_SECRET=your_client_secret")
|
||||
|
||||
# Generated IDs
|
||||
print("\nGenerated IDs:")
|
||||
for key, present in status["generated_ids"].items():
|
||||
print(f" {check_mark(present)} {key}")
|
||||
|
||||
if not status["generated_ids"]["FHIR_PROVIDER_ID"]:
|
||||
print("\n💡 Run setup_fhir_provider.py to create FHIR provider")
|
||||
if not status["generated_ids"]["WORKFLOW_ID"]:
|
||||
print("💡 Run create_workflow.py to create a workflow")
|
||||
|
||||
# Overall status
|
||||
print("\n" + "=" * 60)
|
||||
if core_ready and fhir_ready:
|
||||
print("✅ Ready to create FHIR provider and workflows!")
|
||||
elif core_ready:
|
||||
print("✅ Core credentials ready")
|
||||
print("⚠️ Add FHIR credentials to proceed with provider setup")
|
||||
else:
|
||||
print("⚠️ Add missing credentials to .env to proceed")
|
||||
print("=" * 60 + "\n")
|
||||
|
||||
if verbose:
|
||||
print("\nJSON Output:")
|
||||
print(json.dumps(status, indent=2))
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Check environment variable status without exposing values'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--json',
|
||||
action='store_true',
|
||||
help='Output in JSON format only'
|
||||
)
|
||||
parser.add_argument(
|
||||
'--verbose',
|
||||
action='store_true',
|
||||
help='Include JSON output with formatted output'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
status = check_env_vars()
|
||||
|
||||
if args.json:
|
||||
print(json.dumps(status, indent=2))
|
||||
else:
|
||||
print_status(status, verbose=args.verbose)
|
||||
|
||||
# Exit with error code if core credentials are missing
|
||||
if not all(status["core_credentials"].values()):
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
162
skills/phenoml-workflow/scripts/create_workflow.py
Normal file
162
skills/phenoml-workflow/scripts/create_workflow.py
Normal file
@@ -0,0 +1,162 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Workflow Creation Script
|
||||
|
||||
Creates a PhenoML workflow using configuration from .env or CLI arguments.
|
||||
|
||||
Usage:
|
||||
python3 create_workflow.py
|
||||
python3 create_workflow.py --name "My Workflow" --instructions "..." --sample-data '{"key": "value"}'
|
||||
python3 create_workflow.py --help
|
||||
|
||||
Required .env variables:
|
||||
PHENOML_USERNAME, PHENOML_PASSWORD, PHENOML_BASE_URL
|
||||
FHIR_PROVIDER_ID (from setup_fhir_provider.py)
|
||||
|
||||
Workflow configuration (.env or CLI args):
|
||||
WORKFLOW_NAME or --name
|
||||
WORKFLOW_INSTRUCTIONS or --instructions
|
||||
WORKFLOW_SAMPLE_DATA (JSON string) or --sample-data
|
||||
|
||||
Optional:
|
||||
WORKFLOW_DYNAMIC_GENERATION (true/false) or --dynamic-generation
|
||||
WORKFLOW_VERBOSE (true/false) or --verbose
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from phenoml import Client
|
||||
from dotenv import load_dotenv
|
||||
|
||||
def save_to_env(key, value):
|
||||
"""Save or update a key-value pair in .env file"""
|
||||
env_file = ".env"
|
||||
|
||||
if not os.path.exists(env_file):
|
||||
with open(env_file, 'w') as f:
|
||||
f.write(f"{key}={value}\n")
|
||||
return
|
||||
|
||||
with open(env_file, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
found = False
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith(f"{key}="):
|
||||
lines[i] = f"{key}={value}\n"
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
if lines and not lines[-1].endswith('\n'):
|
||||
lines.append('\n')
|
||||
lines.append(f"{key}={value}\n")
|
||||
|
||||
with open(env_file, 'w') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
def str_to_bool(s):
|
||||
"""Convert string to boolean"""
|
||||
return s.lower() in ('true', '1', 'yes', 'y')
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Create a PhenoML workflow')
|
||||
parser.add_argument('--name', help='Workflow name')
|
||||
parser.add_argument('--instructions', help='Workflow instructions')
|
||||
parser.add_argument('--sample-data', help='Sample data as JSON string')
|
||||
parser.add_argument('--dynamic-generation', type=str_to_bool, help='Enable dynamic generation (true/false)')
|
||||
parser.add_argument('--verbose', type=str_to_bool, help='Verbose mode (true/false)')
|
||||
parser.add_argument('--provider-id', help='FHIR provider ID (overrides .env)')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Load environment
|
||||
load_dotenv()
|
||||
|
||||
# Get configuration (CLI args override .env)
|
||||
name = args.name or os.getenv("WORKFLOW_NAME")
|
||||
instructions = args.instructions or os.getenv("WORKFLOW_INSTRUCTIONS")
|
||||
sample_data_str = args.sample_data or os.getenv("WORKFLOW_SAMPLE_DATA")
|
||||
dynamic_generation = args.dynamic_generation if args.dynamic_generation is not None else str_to_bool(os.getenv("WORKFLOW_DYNAMIC_GENERATION", "true"))
|
||||
verbose = args.verbose if args.verbose is not None else str_to_bool(os.getenv("WORKFLOW_VERBOSE", "false"))
|
||||
provider_id = args.provider_id or os.getenv("FHIR_PROVIDER_ID")
|
||||
|
||||
# Validate required fields
|
||||
if not name:
|
||||
print("❌ Error: Workflow name is required")
|
||||
print(" Set WORKFLOW_NAME in .env, or use --name")
|
||||
sys.exit(1)
|
||||
|
||||
if not instructions:
|
||||
print("❌ Error: Workflow instructions are required")
|
||||
print(" Set WORKFLOW_INSTRUCTIONS in .env, or use --instructions")
|
||||
sys.exit(1)
|
||||
|
||||
if not sample_data_str:
|
||||
print("❌ Error: Sample data is required")
|
||||
print(" Set WORKFLOW_SAMPLE_DATA in .env, or use --sample-data")
|
||||
sys.exit(1)
|
||||
|
||||
if not provider_id:
|
||||
print("❌ Error: FHIR provider ID is required")
|
||||
print(" Run setup_fhir_provider.py first, or use --provider-id")
|
||||
sys.exit(1)
|
||||
|
||||
# Parse sample data
|
||||
try:
|
||||
sample_data = json.loads(sample_data_str)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"❌ Error: Invalid JSON in sample data: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
# Initialize PhenoML client
|
||||
print("Initializing PhenoML client...")
|
||||
try:
|
||||
client = Client(
|
||||
username=os.getenv("PHENOML_USERNAME"),
|
||||
password=os.getenv("PHENOML_PASSWORD"),
|
||||
base_url=os.getenv("PHENOML_BASE_URL")
|
||||
)
|
||||
print("✅ PhenoML client initialized\n")
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to initialize PhenoML client: {e}")
|
||||
print(" Make sure PHENOML_USERNAME, PHENOML_PASSWORD, and PHENOML_BASE_URL are set in .env")
|
||||
sys.exit(1)
|
||||
|
||||
# Create workflow
|
||||
print(f"Creating workflow:")
|
||||
print(f" Name: {name}")
|
||||
print(f" Provider ID: {provider_id}")
|
||||
print(f" Dynamic generation: {dynamic_generation}")
|
||||
print(f" Verbose: {verbose}")
|
||||
print(f" Sample data: {json.dumps(sample_data, indent=2)}\n")
|
||||
|
||||
try:
|
||||
workflow = client.workflows.create(
|
||||
name=name,
|
||||
workflow_instructions=instructions,
|
||||
sample_data=sample_data,
|
||||
fhir_provider_id=provider_id,
|
||||
verbose=verbose,
|
||||
dynamic_generation=dynamic_generation
|
||||
)
|
||||
|
||||
workflow_id = workflow.workflow_id
|
||||
print(f"✅ Workflow created successfully!")
|
||||
print(f" Workflow ID: {workflow_id}\n")
|
||||
|
||||
# Save to .env
|
||||
save_to_env("WORKFLOW_ID", workflow_id)
|
||||
print(f"💾 Workflow ID saved to .env")
|
||||
print(f"\n🎉 Workflow creation complete! You can now test it with test_workflow.py")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to create workflow: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
153
skills/phenoml-workflow/scripts/setup_fhir_provider.py
Normal file
153
skills/phenoml-workflow/scripts/setup_fhir_provider.py
Normal file
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
FHIR Provider Setup Script
|
||||
|
||||
Creates a FHIR provider using credentials from .env or CLI arguments.
|
||||
|
||||
Usage:
|
||||
python3 setup_fhir_provider.py
|
||||
python3 setup_fhir_provider.py --name "My FHIR Server" --provider medplum
|
||||
python3 setup_fhir_provider.py --help
|
||||
|
||||
Required .env variables:
|
||||
PHENOML_USERNAME, PHENOML_PASSWORD, PHENOML_BASE_URL
|
||||
FHIR_PROVIDER_BASE_URL, FHIR_PROVIDER_CLIENT_ID, FHIR_PROVIDER_CLIENT_SECRET
|
||||
|
||||
Example FHIR_PROVIDER_BASE_URL values:
|
||||
- Medplum: https://api.medplum.com/fhir/R4
|
||||
- Athena: https://api.preview.platform.athenahealth.com/fhir/r4
|
||||
- Epic: https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4
|
||||
- Cerner: https://fhir-myrecord.cerner.com/r4/[tenant-id]
|
||||
|
||||
Optional .env variables:
|
||||
FHIR_PROVIDER_NAME (default: "FHIR Server")
|
||||
FHIR_PROVIDER_TYPE (default: "medplum")
|
||||
FHIR_AUTH_METHOD (default: "client_secret")
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import argparse
|
||||
from phenoml import Client
|
||||
from dotenv import load_dotenv
|
||||
|
||||
def save_to_env(key, value):
|
||||
"""Save or update a key-value pair in .env file"""
|
||||
env_file = ".env"
|
||||
|
||||
if not os.path.exists(env_file):
|
||||
with open(env_file, 'w') as f:
|
||||
f.write(f"{key}={value}\n")
|
||||
return
|
||||
|
||||
with open(env_file, 'r') as f:
|
||||
lines = f.readlines()
|
||||
|
||||
found = False
|
||||
for i, line in enumerate(lines):
|
||||
if line.startswith(f"{key}="):
|
||||
lines[i] = f"{key}={value}\n"
|
||||
found = True
|
||||
break
|
||||
|
||||
if not found:
|
||||
if lines and not lines[-1].endswith('\n'):
|
||||
lines.append('\n')
|
||||
lines.append(f"{key}={value}\n")
|
||||
|
||||
with open(env_file, 'w') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Create a FHIR provider for PhenoML workflows')
|
||||
parser.add_argument('--name', help='FHIR provider name')
|
||||
parser.add_argument('--provider', help='Provider type (medplum, epic, cerner, etc.)')
|
||||
parser.add_argument('--auth-method', help='Auth method (default: client_secret)')
|
||||
parser.add_argument('--base-url', help='FHIR base URL')
|
||||
parser.add_argument('--client-id', help='Client ID')
|
||||
parser.add_argument('--client-secret', help='Client secret')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Load environment
|
||||
load_dotenv()
|
||||
|
||||
# Get configuration (CLI args override .env)
|
||||
name = args.name or os.getenv("FHIR_PROVIDER_NAME", "FHIR Server")
|
||||
provider_type = args.provider or os.getenv("FHIR_PROVIDER_TYPE", "medplum")
|
||||
auth_method = args.auth_method or os.getenv("FHIR_AUTH_METHOD", "client_secret")
|
||||
|
||||
# Get FHIR provider credentials (CLI args override .env)
|
||||
base_url = args.base_url or os.getenv("FHIR_PROVIDER_BASE_URL")
|
||||
client_id = args.client_id or os.getenv("FHIR_PROVIDER_CLIENT_ID")
|
||||
client_secret = args.client_secret or os.getenv("FHIR_PROVIDER_CLIENT_SECRET")
|
||||
|
||||
# Validate required fields
|
||||
if not base_url:
|
||||
print("❌ Error: FHIR base URL is required")
|
||||
print(" Set FHIR_PROVIDER_BASE_URL in .env, or use --base-url")
|
||||
print("\n Example values:")
|
||||
print(" - Medplum: https://api.medplum.com/fhir/R4")
|
||||
print(" - Athena: https://api.preview.platform.athenahealth.com/fhir/r4")
|
||||
print(" - Epic: https://fhir.epic.com/interconnect-fhir-oauth/api/FHIR/R4")
|
||||
print(" - Cerner: https://fhir-myrecord.cerner.com/r4/[tenant-id]")
|
||||
sys.exit(1)
|
||||
|
||||
if not client_id:
|
||||
print("❌ Error: Client ID is required")
|
||||
print(" Set FHIR_PROVIDER_CLIENT_ID in .env, or use --client-id")
|
||||
sys.exit(1)
|
||||
|
||||
if not client_secret:
|
||||
print("❌ Error: Client secret is required")
|
||||
print(" Set FHIR_PROVIDER_CLIENT_SECRET in .env, or use --client-secret")
|
||||
sys.exit(1)
|
||||
|
||||
# Initialize PhenoML client
|
||||
print("Initializing PhenoML client...")
|
||||
try:
|
||||
client = Client(
|
||||
username=os.getenv("PHENOML_USERNAME"),
|
||||
password=os.getenv("PHENOML_PASSWORD"),
|
||||
base_url=os.getenv("PHENOML_BASE_URL")
|
||||
)
|
||||
print("✅ PhenoML client initialized\n")
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to initialize PhenoML client: {e}")
|
||||
print(" Make sure PHENOML_USERNAME, PHENOML_PASSWORD, and PHENOML_BASE_URL are set in .env")
|
||||
sys.exit(1)
|
||||
|
||||
# Create FHIR provider
|
||||
print(f"Creating FHIR provider:")
|
||||
print(f" Name: {name}")
|
||||
print(f" Provider: {provider_type}")
|
||||
print(f" Base URL: {base_url}")
|
||||
print(f" Auth method: {auth_method}\n")
|
||||
|
||||
try:
|
||||
fhir_provider = client.fhir_provider.create(
|
||||
name=name,
|
||||
provider=provider_type,
|
||||
auth_method=auth_method,
|
||||
base_url=base_url,
|
||||
client_id=client_id,
|
||||
client_secret=client_secret
|
||||
)
|
||||
|
||||
provider_id = fhir_provider.data.id
|
||||
print(f"✅ FHIR provider created successfully!")
|
||||
print(f" Provider ID: {provider_id}\n")
|
||||
|
||||
# Save to .env
|
||||
save_to_env("FHIR_PROVIDER_ID", provider_id)
|
||||
print(f"💾 Provider ID saved to .env")
|
||||
print(f"\n🎉 Setup complete! You can now create workflows using this provider.")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to create FHIR provider: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
135
skills/phenoml-workflow/scripts/test_workflow.py
Normal file
135
skills/phenoml-workflow/scripts/test_workflow.py
Normal file
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Workflow Testing Script
|
||||
|
||||
Tests a PhenoML workflow using test data from .env, CLI arguments, or a JSON file.
|
||||
|
||||
Usage:
|
||||
python3 test_workflow.py
|
||||
python3 test_workflow.py --workflow-id abc123 --input-data '{"patient": "Smith"}'
|
||||
python3 test_workflow.py --input-file test_data.json
|
||||
python3 test_workflow.py --help
|
||||
|
||||
Required .env variables:
|
||||
PHENOML_USERNAME, PHENOML_PASSWORD, PHENOML_BASE_URL
|
||||
|
||||
Test configuration (.env or CLI args):
|
||||
WORKFLOW_ID or --workflow-id
|
||||
WORKFLOW_TEST_DATA (JSON string) or --input-data or --input-file
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import argparse
|
||||
from phenoml import Client
|
||||
from dotenv import load_dotenv
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Test a PhenoML workflow')
|
||||
parser.add_argument('--workflow-id', help='Workflow ID to test')
|
||||
parser.add_argument('--input-data', help='Input data as JSON string')
|
||||
parser.add_argument('--input-file', help='Path to JSON file with input data')
|
||||
parser.add_argument('--output-file', help='Save results to JSON file')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Load environment
|
||||
load_dotenv()
|
||||
|
||||
# Get configuration (CLI args override .env)
|
||||
workflow_id = args.workflow_id or os.getenv("WORKFLOW_ID")
|
||||
|
||||
# Validate workflow ID
|
||||
if not workflow_id:
|
||||
print("❌ Error: Workflow ID is required")
|
||||
print(" Set WORKFLOW_ID in .env, or use --workflow-id")
|
||||
sys.exit(1)
|
||||
|
||||
# Get input data from various sources
|
||||
input_data = None
|
||||
|
||||
if args.input_file:
|
||||
# Load from file
|
||||
try:
|
||||
with open(args.input_file, 'r') as f:
|
||||
input_data = json.load(f)
|
||||
except FileNotFoundError:
|
||||
print(f"❌ Error: File not found: {args.input_file}")
|
||||
sys.exit(1)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"❌ Error: Invalid JSON in file {args.input_file}: {e}")
|
||||
sys.exit(1)
|
||||
elif args.input_data:
|
||||
# Parse from CLI arg
|
||||
try:
|
||||
input_data = json.loads(args.input_data)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"❌ Error: Invalid JSON in input data: {e}")
|
||||
sys.exit(1)
|
||||
else:
|
||||
# Try to load from .env
|
||||
test_data_str = os.getenv("WORKFLOW_TEST_DATA")
|
||||
if test_data_str:
|
||||
try:
|
||||
input_data = json.loads(test_data_str)
|
||||
except json.JSONDecodeError as e:
|
||||
print(f"❌ Error: Invalid JSON in WORKFLOW_TEST_DATA: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
if not input_data:
|
||||
print("❌ Error: Input data is required")
|
||||
print(" Set WORKFLOW_TEST_DATA in .env, use --input-data, or use --input-file")
|
||||
sys.exit(1)
|
||||
|
||||
# Initialize PhenoML client
|
||||
print("Initializing PhenoML client...")
|
||||
try:
|
||||
client = Client(
|
||||
username=os.getenv("PHENOML_USERNAME"),
|
||||
password=os.getenv("PHENOML_PASSWORD"),
|
||||
base_url=os.getenv("PHENOML_BASE_URL")
|
||||
)
|
||||
print("✅ PhenoML client initialized\n")
|
||||
except Exception as e:
|
||||
print(f"❌ Failed to initialize PhenoML client: {e}")
|
||||
print(" Make sure PHENOML_USERNAME, PHENOML_PASSWORD, and PHENOML_BASE_URL are set in .env")
|
||||
sys.exit(1)
|
||||
|
||||
# Execute workflow
|
||||
print(f"Testing workflow:")
|
||||
print(f" Workflow ID: {workflow_id}")
|
||||
print(f" Input data:")
|
||||
print(json.dumps(input_data, indent=4))
|
||||
print("\n⏳ Executing workflow (this may take a moment)...\n")
|
||||
|
||||
try:
|
||||
result = client.workflows.execute(
|
||||
id=workflow_id,
|
||||
input_data=input_data
|
||||
)
|
||||
|
||||
print("✅ Workflow executed successfully!\n")
|
||||
print("=" * 60)
|
||||
print("EXECUTION RESULTS")
|
||||
print("=" * 60)
|
||||
|
||||
result_dict = result.model_dump()
|
||||
print(json.dumps(result_dict, indent=2))
|
||||
|
||||
# Save to file if requested
|
||||
if args.output_file:
|
||||
with open(args.output_file, 'w') as f:
|
||||
json.dump(result_dict, f, indent=2)
|
||||
print(f"\n💾 Results saved to {args.output_file}")
|
||||
|
||||
print("\n🎉 Test complete!")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Workflow execution failed: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user