The ViaFoundry SDK and CLI provide a powerful way to interact with ViaFoundry APIs. Whether you're a developer integrating with the API or a user looking for a simple command-line interface, this package has you covered.
- Installation
- CLI Usage
- 1. Configure the CLI or SDK
- 2. Discover Endpoints
- 3. Call an Endpoint
- 4. Reports Management
- 5. Example: Launch an App
- 6. Process Management
- List All Processes
- Get Process Details
- Get Revisions for a Process
- Check Process Usage
- Duplicate a Process
- Create a Menu Group
- Get Menu Group by Name
- Get Parameters
- Create a Process Config
- Create a Process
- Update a Process
- Delete a Process
- List All Parameters
- Create a Parameter
- Update a Parameter
- Delete a Parameter
- Logging
- SDK Usage
- 1. Import the SDK
- 2. Initialize the Client
- 3. Authenticate and Configure
- 4. Discover Endpoints
- 5. Reports Managment
- 6. Process Managment SDK
- List All Processes
- Get Process Details
- Get Revisions for a Process
- Check Process Usage
- Duplicate a Process
- Create a Menu Group
- Get Menu Group by Name
- Get Parameters
- Create a Process Config
- Create a Process
- Update a Process
- Delete a Process
- List All Parameters
- Create a Parameter
- Update a Parameter
- Delete a Parameter
- Release a version
- Summary
-
Install via pip:
pip install viafoundry_sdk
-
Verify Installation:
- For CLI:
foundry --help
- For SDK:
Open a Python interpreter and ensure the package is importable:
import viafoundry
- For CLI:
The CLI provides quick access to ViaFoundry functionalities without needing to write code. Below are some common commands.
Authenticate with your ViaFoundry account interactively:
foundry configureThis will prompt you to:
- Enter API hostname
- Choose authentication method:
- Token (recommended)
- Username and Password
foundry configure --hostname https://your-api-host.com --token your-tokenfoundry configure --hostname https://your-api-host.com --username your-username --password your-passwordOptions:
--hostname: The URL of the ViaFoundry API (e.g.,https://viafoundry.comorhttp://localhost:8081)--token: Personal access token (recommended for security)--username: Your username (used with password authentication)--password: Your password (used with username authentication)
The discover command in the ViaFoundry CLI has been enhanced to support filtering of API endpoints. This feature allows users to narrow down the list of endpoints based on specific search criteria.
foundry discover [OPTIONS]--as-json: Output the filtered results in JSON format.--search: Search term to filter endpoints. Supports free-text or key-value format.
Search across all fields (endpoint, method, and description) using a case-insensitive match.
foundry discover --search "reports"Available API Endpoints:
Endpoint: /run/v1/{runId}/reports
Method: get
Description: 'View the metdata and resource paths for run reports'
Endpoint: /run/v1/{runId}/reports-dirs
Method: get
Description: 'Upload report directories'
Endpoint: /run/v1/{runId}/reports/upload/:runUUID
Method: post
Description: 'list report directories'
Data to send: {
"type": "object",
"properties": {
"dir": {
"type": "string",
"description": "The path to the report directory",
"example": "/path/to/report"
}
},
"additionalProperties": false
}
Target specific fields by specifying a key=value pair.
endpoint: Filters based on the endpoint path.description: Filters based on the description text.
foundry discover --search "endpoint=reports"foundry discover --search "description=parameters" Add the --as-json flag to get the filtered results in JSON format.
foundry discover --as-json --search "reports"The enhanced discover command allows you to:
- Filter API endpoints by free-text or key-value pairs.
- View results in human-readable text or JSON format.
- Customize your search to focus on specific fields such as
endpointordescription.
Send a request to a specific endpoint:
foundry call --method GET --endpoint /api/v1/example --params '{"key": "value"}'Options:
--method: HTTP method (GET,POST, etc.).--endpoint: API endpoint path (e.g.,/api/v1/example).--params: Optional query parameters in JSON format (e.g.,{"key": "value"}).--data: Optional request body in JSON format (e.g.,{"key": "value"}).
Work with reports using the foundry reports command group.
Fetch JSON data for a report:
foundry reports fetch REPORT_IDor
foundry reports fetch --reportID=REPORT_IDList all unique processes in a report:
foundry reports list-processes REPORT_IDor
foundry reports list-processes --reportID=REPORT_IDList files to get file paths for a specific process within a report:
foundry reports list-files REPORT_ID PROCESS_NAMEor
foundry reports list-files --reportID=REPORT_ID --processName=PROCESS_NAMEDownload a file from a report:
foundry reports download-file REPORT_ID FILE_PATH --download-dir /path/to/saveor
foundry reports download-file --reportID=REPORT_ID --filePath=FILE_PATH --download-dir /path/to/saveList all files across all processes in a report.
foundry reports list-all-files REPORT_IDor
foundry reports list-all-files --reportID=REPORT_IDYou can list possible directories in the report section that you can use while uploading files using the CLI:
foundry reports get-report-dirs REPORT_ID
or
foundry reports get-report-dirs --reportID REPORT_IDYou can upload a file to a specific report using the CLI:
Options:
--reportIDTEXT Report ID (alternative to positional argument).--filePathPATH Local file path (alternative to positional argument).--remoteDirTEXT Directory name for organizing files (alternative to positional argument).
viafoundry upload-report-file REPORT_ID FILE_PATH REPORT-DIRor
viafoundry upload-report-file --reportID REPORT_ID --filePath FILE_PATH remoteDir REMOTE-DIRReplace REPORT_ID with the target report’s ID and FILE_PATH with the path to the file you want to upload. Use the --dir option to specify a directory.
Send a POST request to a specific endpoint to launch an app:
foundry call --endpoint /api/app/v1/call/1 --method POST --data '{"type": "standalone"}'Manage processes with commands like listing, creating, updating, and deleting processes.
foundry process list-processesfoundry process get-process <process_id>
# Or
foundry process get-process --processID <process_id>foundry process get-revisions <process_id>
# Or
foundry process get-revisions --processID <process_id>foundry process check-usage <process_id>
# Or
foundry process check-usage --processID <process_id>foundry process duplicate-process <process_id>
# Or
foundry process duplicate-process --processID <process_id>foundry process create-menu-group <menu_name>
# Or
foundry process create-menu-group --menuName <menu_name>Find a menu group by its name and print its ID:
foundry process get-menu-group-by-name <group_name>Get parameters by name, qualifier, file type, or ID:
foundry process get-parameters --name <name> --qualifier <qualifier> --filetype <filetype> --id <id>All options are optional and can be combined.
Generate a full process configuration (as JSON) using menu group and parameter filters:
foundry process create-process-config \
--name "Process Name" \
--menu-group "Menu Group Name" \
--input-params input_params.json \
--output-params output_params.json \
--summary "Summary" \
--script-body "echo Hello" \
--script-language bash \
--script-header "" \
--script-footer "" \
--permission-settings permission_settings.json \
--revision-comment "Initial revision"--input-paramsand--output-paramsshould be JSON files describing parameters.--permission-settingsis optional and should be a JSON file.
Pass the process data as a JSON file:
foundry process create-process <path_to_json>
# Or
foundry process create-process --processData <path_to_json>foundry process update-menu-group <menu_group_id> <menu_name>
# Or
foundry process update-menu-group --menuGroupID <menu_group_id> --menuName <menu_name>Pass the updated process data as a JSON file:
foundry process update-process <process_id> <path_to_json>
# Or
foundry process update-process --processID <process_id> --processData <path_to_json>foundry process delete-process <process_id>
# Or
foundry process delete-process --processID <process_id>foundry process list-parametersPass the parameter data as a JSON file:
foundry process create-parameter <path_to_json>
# Or
foundry process create-parameter --parameterData <path_to_json>Pass the updated parameter data as a JSON file:
foundry process update-parameter <parameter_id> <path_to_json>
# Or
foundry process update-parameter --parameterID <parameter_id> --parameterData <path_to_json>foundry process delete-parameter <parameter_id>
# Or
foundry process delete-parameter --parameterID <parameter_id>Errors and debug information are logged to viafoundry_errors.log in the current working directory. Ensure this file is accessible for troubleshooting.
The SDK allows developers to programmatically interact with ViaFoundry APIs. Below are some examples.
from viafoundry.client import ViaFoundryClientProvide the path to your configuration file or set up authentication manually:
client = ViaFoundryClient(config_path="path/to/config.json")Example config.json:
{
"hostname": "https://your-api-host.com",
"token": "your-auth-token"
}If you want to enable recording session while working in J
If you already authenticated using CLI or want to use default file (~/.viaenv). You can use like below.
client = ViaFoundryClient()Configure with a personal access token:
client = ViaFoundryClient()
client.configure_auth_token(
hostname="https://your-api-host.com",
token="your-personal-access-token"
)Alternatively, configure with username and password:
client = ViaFoundryClient()
client.configure_auth(
hostname="https://your-api-host.com",
username="your-username",
password="your-password"
)Retrieve a list of available API endpoints:
endpoints = client.discover()
print("Discovered Endpoints:", endpoints)The discover function in the ViaFoundry SDK has been enhanced to support filtering of API endpoints. This feature allows developers to programmatically narrow down the list of endpoints based on specific search criteria.
def discover(self, search=None, as_json=False):
"""
Discover available API endpoints with optional filtering.
Parameters:
search (str): Search term to filter endpoints. Supports free-text or 'key=value' format.
as_json (bool): If True, return the filtered results as JSON.
Returns:
dict or str: Filtered endpoints as a dictionary (default) or JSON string if as_json is True.
"""search:- Free-text search: Searches across all fields (
endpoint,method, anddescription) using a case-insensitive match. - Key-value search: Targets specific fields such as
endpointordescription.
- Free-text search: Searches across all fields (
as_json: IfTrue, the function returns the results in JSON format.
Search across all fields using a case-insensitive match.
from viafoundry.client import ViaFoundryClient
client = ViaFoundryClient()
filtered_endpoints = client.discover(search="reports")
for endpoint, methods in filtered_endpoints.items():
for method, details in methods.items():
print(f"Endpoint: {endpoint}")
print(f"Method: {method}")
print(f"Description: {details.get('description', 'No description available')}")Endpoint: /run/v1/{runId}/reports
Method: get
Description: View the metdata and resource paths for run reports
Target specific fields using key=value format.
# Search in the 'endpoint' field
filtered_endpoints = client.discover(search="endpoint=reports")
print(filtered_endpoints)
# Search in the 'description' field
filtered_endpoints = client.discover(search="description=logs")
print(filtered_endpoints)Get the filtered results in JSON format by setting as_json=True.
filtered_endpoints_json = client.discover(search="logs", as_json=True)
print(filtered_endpoints_json)Fetch JSON data for a specific report:
report_data = client.reports.fetch_report_data(report_id="12345")List unique processes in the fetched report data:
process_names = client.reports.get_process_names(report_data)
print("Processes:", process_names)List all files for a specific process in the report:
files = client.reports.get_file_names(report_data, process_name="myProcess")
print(files)Download a specific file from the report:
loaded_data = client.reports.load_file(
report_data,
file_path="dir/example.txt"
)
print(loaded_data)Download a specific file from the report:
client.reports.download_file(
report_data,
file_path="dir/example.txt",
download_dir="/path/to/save"
)List all files across all processes in the report:
all_files = client.reports.get_all_files(report_data)
print(all_files)Uploads a file to a specific report and organizes it in a specified directory. Be sure to learn how to retrieve the upload directory from #11.
def upload_report_file(self, report_id, local_file_path, dir=None):
\"\"\"Upload a file to a specific report.
Args:
report_id (str): The ID of the report.
local_file_path (str): The local path to the file being uploaded.
dir (str, optional): Directory name for organizing files.
Returns:
dict or str: Response from the server.
\"\"\"client = ViaFoundryClient()
response = client.reports.upload_report_file(
report_id="1",
local_file_path="/path/to/your/file.csv",
dir="summary"
)
print("Upload Response:", response)Upload Response: OK
Fetches unique directories from a report after the pubweb segment in the routePath.
def get_report_dirs(self, report_id):
\"\"\"Get possible directories following 'pubweb' in the routePath.
Args:
report_id (str): The ID of the report.
Returns:
list: A list of unique directories found after 'pubweb'.
\"\"\"client = ViaFoundryClient()
directories = client.reports.get_report_dirs("1")
print("Directories:", directories){
"directories": [
"salmon_count",
"star_count",
"kallisto_count"
]
}Fetches all routePath values from a specific report.
def get_all_report_paths(self, report_id):
\"\"\"Get all routePath values for a specific report.
Args:
report_id (str): The ID of the report.
Returns:
list: A list of all routePath values.
\"\"\"client = ViaFoundryClient()
all_paths = client.reports.get_all_report_paths("1")
print("Route Paths:", all_paths)Route Paths: [
"/report-resources/dir1/pubweb/salmon_count",
"/report-resources/dir1/pubweb/star_count",
"/report-resources/dir1/pubweb/kallisto_count"
]
from viafoundry.client import ViaFoundryClient
client = ViaFoundryClient(config_path="path_to_config.json")
process = client.processprocesses = process.list_processes()
print(processes)process_details = process.get_process(process_id="12345")
print(process_details)revisions = process.get_process_revisions(process_id="12345")
print(revisions)usage = process.check_process_usage(process_id="12345")
print(usage)duplicate_response = process.duplicate_process(process_id="12345")
print(duplicate_response)response = process.create_menu_group(name="New Menu Group")
print(response)Find a menu group by its name and get its ID:
group_id = process.get_menu_group_by_name("Menu Group Name")
print(group_id)Get parameters by name, qualifier, file type, or ID:
filtered = process.get_parameters(
name="param_name",
qualifier="file",
fileType="fasta",
id_="123"
)
print(filtered)All arguments are optional and can be combined.
Generate a full process configuration (as a Python dict) using menu group and parameter filters:
input_params = [
{"name": "input1", "qualifier": "file", "fileType": "fasta"},
# ...
]
output_params = [
{"qualifier": "file", "fileType": "txt"},
# ...
]
config = process.create_process_config(
name="Process Name",
menu_group_name="Menu Group Name",
input_params=input_params,
output_params=output_params,
summary="Summary",
script_body="echo Hello",
script_language="bash",
script_header="",
script_footer="",
permission_settings={"viewPermissions": 3, "writeGroupIds": []},
revision_comment="Initial revision"
)
print(config)For each input and output parameter, the funciton will search for mathching parameters and use them if found. If the parameter does not exist, a new one will be created. In this case the fields "name" and "qualifier" are required.
process_data = {
"name": "Example Process",
"summary": "An example process",
"menuGroupId": 1,
# Additional fields...
}
response = process.create_process(process_data=process_data)
print(response)response = process.update_menu_group(menu_group_id=1, name="Updated Menu Group")
print(response)updated_data = {
"name": "Updated Process",
"summary": "Updated description",
# Additional fields...
}
response = process.update_process(process_id="12345", process_data=updated_data)
print(response)response = process.delete_process(process_id="12345")
print(response)parameters = process.list_parameters()
print(parameters)parameter_data = {
"name": "Parameter Name",
"qualifier": "file",
"fileType": "fasta",
}
response = process.create_parameter(parameter_data=parameter_data)
print(response)updated_parameter = {
"name": "Updated Parameter Name",
"qualifier": "file",
"fileType": "fastq",
}
response = process.update_parameter(parameter_id="123", parameter_data=updated_parameter)
print(response)response = process.delete_parameter(parameter_id="123")
print(response)- First get a new version
For patch release
poetry version patch
For minor release
poetry version minor
For major release
poetry version major
- Build it
poetry build
- Set up PyPI credentials
Option A: Configure manually You can set your PyPI token securely:
poetry config pypi-token.pypi <your-token>
Option B: Use environment variable Set POETRY_PYPI_TOKEN_PYPI in your shell or CI environment:
export POETRY_PYPI_TOKEN_PYPI=<your-token>
In GitHub Actions, define this as a secret and reference it like:
env:
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }}
- Publish the package
Once your token is set, run:
poetry publish --build
The enhanced discover function in the SDK allows you to:
- Filter API endpoints by free-text or key-value pairs.
- Retrieve results as a Python dictionary or JSON string.
- Focus your search on specific fields like
endpointordescription. - Access reports data and upload/download them to use in further analysis in the report section
- Access process section and add remove parameters, processes and versions of the processes.
This makes it easier to programmatically explore and interact with the available API endpoints in ViaFoundry.