APIs cookbook
Each recipe aims for clarity, ease of use, and customizability for different use cases.
1. Setup instructions
To get started with the examples, Python is used to interact with SysON’s features and data. Python offers a powerful way to automate tasks, handle API calls, and process data, making it an ideal choice for this purpose. Follow the steps after to set up your environment and get everything ready to run the provided code snippets.
1.1. Step 1: Install required Python libraries
Confirm you have the following Python libraries installed before running the code snippets:
-
requests
: For making HTTP requests to the SysML v2 API. -
pandas
: For organizing and manipulating data.
To install these libraries, run:
pip install requests pandas
1.2. Step 2: Configure SysML v2 API access
# These examples are adapted from the SysML v2 API Cookbook, available at
# https://github.com/Systems-Modeling/SysML-v2-API-Cookbook, maintained by the
# Object Management Group (OMG).
# The original cookbook is designed for use with Jupyter Lab.
# These examples have been adapted to run as standalone Python scripts, making
# them suitable for use in various environments, including SysON.
# They showcase practical usage scenarios and may include additional functionality
# or modifications tailored to specific needs.
import argparse
def init_sysmlv2_api():
host = "http://localhost:8080/api/rest" # Replace with your actual API host URL (1)
return host
def parse_arguments():
# Parse command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument(
"project_id",
type=str,
help="The project ID.",
)
parser.add_argument(
"element_id",
type=str,
nargs="?", # This makes element_id optional
help="The element ID (optional).",
)
return parser.parse_args()
Replace http://localhost:8080 with the actual URL of your API server if hosted elsewhere.
|
What this code does:
1 | Define the base host: Assigns the variable host with the base URL of the SysML v2 API server. |
In the examples, the SysON server uses a randomization function to generate unique IDs, so outputs can differ when you run the examples on your project. |
Other code snippets use this function. To run it, see the following section about recipes.
1.3. Step 3: Test code snippets
Once you have configured the SysML v2 API access, you can start testing the recipes.
1.4. Troubleshooting
-
Error Handling:
-
Check endpoint URLs,
project_id
,commit_id
, andauthentication
tokens if the API returns errors: for example, 400 or 500 status codes. -
Confirm the API is running.
-
-
Empty Responses:
-
Verify that queried elements exist within the specified project and commit.
-
Use the SysON web interface for visual inspection.
-
-
Recursive Function Depth:
-
For large models, manage recursion depth appropriately.
-
Change the logic to handle large datasets by limiting recursion depth.
-
2. Recipes
2.1. Project and commit recipe
Learn how to manage projects and retrieve related commits programmatically. Each recipe includes a detailed explanation, step-by-step instructions, and code snippets.
Recipes covered:
-
Get Projects: Fetch and display all projects currently available on the server.
-
Create a New Project: Create a new project with a unique name.
-
Get Commits: Retrieve a list of commits for a specific project.
2.1.1. Get projects
This code example demonstrates how to use Python’s requests library to interact with the SysON API and retrieve a list of projects.
It sends a GET
request to the API endpoint for projects, processes the response, and prints the name and ID of each project.
Example script to fetch projects:
# These examples are adapted from the SysML v2 API Cookbook, available at
# https://github.com/Systems-Modeling/SysML-v2-API-Cookbook, maintained by the
# Object Management Group (OMG).
# The original cookbook is designed for use with Jupyter Lab.
# These examples have been adapted to run as standalone Python scripts, making
# them suitable for use in various environments, including SysON.
# They showcase practical usage scenarios and may include additional functionality
# or modifications tailored to specific needs.
import requests (1)
from init_api import init_sysmlv2_api
def fetch_projects(host): (2)
projects_url = f"{host}/projects" (3)
response = requests.get(projects_url) (4)
if response.status_code == 200: (5)
projects = response.json()
for project in projects:
print(f"Project Name: {project['name']}, ID: {project['@id']}")
else:
print(f"Error fetching projects: {response.status_code} - {response.text}")
if __name__ == "__main__":
host = init_sysmlv2_api()
# Get the projects
fetch_projects(host)
What this code does:
1 | Import required libraries:
|
2 | Define the fetch_projects function with one parameter:
|
3 | Constructs the API endpoint address for fetching projects. |
4 | Sends a GET request to the API, passing the SysON address as a query parameter. |
5 | Handles the API response:
|
Run the script:
$ python fetch_projects.py
Output:
Project Name: Batmobile, ID: 63a03bd8-a81a-4818-801a-01790ce8a086
2.1.2. Create a new project
This recipe demonstrates how to create a new project in SysON using Python.
It sends a POST
request to the /projects
endpoint to create a new project with a unique name and description.
Example script to create a new project:
# These examples are adapted from the SysML v2 API Cookbook, available at
# https://github.com/Systems-Modeling/SysML-v2-API-Cookbook, maintained by the
# Object Management Group (OMG).
# The original cookbook is designed for use with Jupyter Lab.
# These examples have been adapted to run as standalone Python scripts, making
# them suitable for use in various environments, including SysON.
# They showcase practical usage scenarios and may include additional functionality
# or modifications tailored to specific needs.
import requests (1)
from init_api import init_sysmlv2_api
from fetch_projects import fetch_projects
from datetime import datetime
def create_project(host, project_name): (2)
# Define project data as query parameters
project_params = {
"name": project_name
}
# API endpoint to create a project
url = f"{host}/projects" (3)
# Send POST request with query parameters
response = requests.post(url, params=project_params) (4)
# Check if the project creation was successful
if response.status_code == 201: (5)
response_json = response.json()
print("Project created successfully:")
print(f"Project ID: {response_json.get("@id", "Unknown ID")}")
print(f"Project Name: {response_json.get('name', 'Unknown Name')}")
else:
print(f"Error creating project: {response.status_code} - {response.text}")
if __name__ == "__main__":
host = init_sysmlv2_api()
# Fetch and display the list of projects currently available on the server
print("Fetching the list of projects currently available on the server:")
fetch_projects(host)
# Create a new project with a unique name by appending a timestamp
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
project_name = f"New Project - {timestamp}"
create_project(host, project_name)
# Fetch and display the updated list of projects after creating the new project
print("Fetching the updated list of projects after creating a new project:")
fetch_projects(host)
What this code does:
1 | Import required libraries:
|
2 | Define the create_project function with two parameters:
|
3 | Constructs the API endpoint URL of project creation. |
4 | Sends a POST request to the API, passing the project name as a query parameter. |
5 | Handles the API response:
|
Run the script:
$ python create_project.py
Output:
Fetching the list of projects currently available on the server:
Project Name: Batmobile, ID: 63a03bd8-a81a-4818-801a-01790ce8a086
Project created successfully:
Project ID: d967b937-304f-43a9-8af6-b1f3a9d6adbe
Project Name: New Project - 2024-12-31 10:52:56
Fetching the updated list of projects after creating a new project:
Project Name: Batmobile, ID: 63a03bd8-a81a-4818-801a-01790ce8a086
Project Name: New Project - 2024-12-31 10:52:56, ID: d967b937-304f-43a9-8af6-b1f3a9d6adbe
2.1.3. Get commits
SysON always returns a single branch with a single commit. |
This example extends the functionality by fetching the commit associated with a specific project ID.
It constructs an address based on the host and project ID, sends a GET
request, and prints the ID of the retrieved commit.
Example script to fetch commits:
# These examples are adapted from the SysML v2 API Cookbook, available at
# https://github.com/Systems-Modeling/SysML-v2-API-Cookbook, maintained by the
# Object Management Group (OMG).
# The original cookbook is designed for use with Jupyter Lab.
# These examples have been adapted to run as standalone Python scripts, making
# them suitable for use in various environments, including SysON.
# They showcase practical usage scenarios and may include additional functionality
# or modifications tailored to specific needs.
import requests (1)
from init_api import parse_arguments
from init_api import init_sysmlv2_api
def fetch_commits(host, project_id): (2)
commits_url = f"{host}/projects/{project_id}/commits" (3)
response = requests.get(commits_url) (4)
if response.status_code == 200: (5)
commits = response.json()
for commit in commits:
print(f"Commit ID: {commit['@id']}")
return commits
else:
print(f"Error fetching commits: {response.status_code} - {response.text}")
return None
# Retrieves the latest commit for a given project.
def get_last_commit_id(host, project_id):
commits = fetch_commits(host, project_id)
if commits:
last_commit = commits[-1] if commits else None
if last_commit:
last_commit_id = last_commit['@id']
print(f"Last Commit ID: {last_commit_id}")
return last_commit_id
else:
print("No commits available.")
return None
if __name__ == "__main__":
args = parse_arguments()
host = init_sysmlv2_api()
project_id = args.project_id
fetch_commits(host, project_id)
What this code does:
1 | Import required libraries:
|
2 | Define the fetch_commits Function with two parameters:
|
3 | Constructs the API endpoint URL for fetching commits. |
4 | Sends a GET request to the API, passing the SysON address and the project ID as a query parameter. |
5 | Handles the API response:
|
Run the script:
$ python fetch_commits.py your-project-id
Output:
Commit ID: 63a03bd8-a81a-4818-801a-01790ce8a086
2.2. Element owned elements recipe
Learn how to retrieve owned elements programmatically. Each recipe includes a detailed explanation, step-by-step instructions, and sample code.
Recipes covered:
-
Get Owned Elements: Retrieve owned elements.
2.2.1. Get owned elements
This example demonstrates how to recursively navigate through the hierarchical structure of elements by using the SysON API. The script starts from a specific element identified by its ID and retrieves its details along with any "owned elements." The function calls itself recursively to explore all child elements in the hierarchy, printing their names, IDs, and types in an indented format to show the hierarchy visually.
Example script to get owned elements:
# These examples are adapted from the SysML v2 API Cookbook, available at
# https://github.com/Systems-Modeling/SysML-v2-API-Cookbook, maintained by the
# Object Management Group (OMG).
# The original cookbook is designed for use with Jupyter Lab.
# These examples have been adapted to run as standalone Python scripts, making
# them suitable for use in various environments, including SysON.
# They showcase practical usage scenarios and may include additional functionality
# or modifications tailored to specific needs.
import requests
from init_api import parse_arguments
from init_api import init_sysmlv2_api
from fetch_commits import get_last_commit_id
# Function to fetch an element and print its name and type
def get_element(host, project_id, commit_id, element_id, indent):
# Fetch the element in the given commit of the given project
element_url = f"{host}/projects/{project_id}/commits/{commit_id}/elements/{element_id}" (3)
response = requests.get(element_url) (1)
if response.status_code == 200:
element_data = response.json()
element_name_to_print = element_data['name'] if element_data['name'] else 'N/A'
element_id = element_data ['@id']
element_type = element_data ['@type']
print(f"{indent} - {element_name_to_print} (id = {element_id} , type = {element_type})") (2)
return element_data
else:
return None
# Fetches immediate owned elements for a given element
def get_owned_elements_immediate(host, project_id, commit_id, element_id, indent):
element_data = get_element(host, project_id, commit_id, element_id, indent)
if element_data:
owned_elements = element_data['ownedElement']
if len(owned_elements) > 0:
for owned_element in owned_elements:
get_element(host, project_id, commit_id, owned_element['@id'], indent + ' ')
else:
print(f"Unable to fetch element with id '{element_id}' in commit '{commit_id}' of project '{project_id}'")
# Fetches owned elements recursively for a given element
def get_owned_elements(host, project_id, commit_id, element_id, indent):
element_data = get_element(host, project_id, commit_id, element_id, indent)
if element_data: (3)
owned_elements = element_data['ownedElement']
if len(owned_elements) > 0:
for owned_element in owned_elements:
get_owned_elements(host, project_id, commit_id, owned_element['@id'], indent+' ')
else:
print(f"Unable to fetch element with id '{element_id}' in commit '{commit_id}' of project '{project_id}'") (4)
if __name__ == "__main__":
args = parse_arguments()
host = init_sysmlv2_api()
project_id = args.project_id
commit_id = get_last_commit_id(host, project_id)
element_id = args.element_id
#Get owned elements (immediate) for the given element in the given commit of the given project
print("Immediate Owned Elements:")
get_owned_elements_immediate(host, project_id, commit_id, element_id, '')
# Get owned elements (recursive) for the given element in the given commit of the given project
print("\nRecursive Owned Elements:")
get_owned_elements(host, project_id, commit_id, element_id, '')
What this code does:
1 | Fetches an Element: Sends a GET request to the SysON API to retrieve details about an element specified by its ID. |
2 | Prints Element Details: Displays the element’s name, ID, and type in a formatted, indented way. |
3 | Processes Owned Elements: Checks for owned elements and calls itself recursively for each one. |
4 | Recursive Traversal: Continues recursing through hierarchical levels until it explores and prints all owned elements. |
This approach helps visualize the structure of complex models or systems, where elements are organized hierarchically. It highlights how to navigate relationships between elements efficiently by using the SysON API.
Run the script:
$ python get_owned_elements.py
Output example:
Commit ID: 63a03bd8-a81a-4818-801a-01790ce8a086
Last Commit ID: 63a03bd8-a81a-4818-801a-01790ce8a086
Immediate Owned Elements:
- Batmobile (Definition)
- problemStatement (ReferenceUsage)
- systemIdea (ReferenceUsage)
- seat (PartUsage)
- body (PartUsage)
- wheels (PartUsage)
- frontLeftWheel (PartUsage)
- frontRightWheel (PartUsage)
- rearLeftWheel (PartUsage)
- rearRightWheel (PartUsage)
- battery (PartUsage)
- batmobileEngine (PartUsage)
Recursive Owned Elements:
- Batmobile (Definition)
- problemStatement (ReferenceUsage)
- N/A (LiteralString)
- systemIdea (ReferenceUsage)
- N/A (LiteralString)
- seat (PartUsage)
- body (PartUsage)
- wheels (PartUsage)
- frontLeftWheel (PartUsage)
- frontRightWheel (PartUsage)
- rearLeftWheel (PartUsage)
- rearRightWheel (PartUsage)
- battery (PartUsage)
- powerPort (PortUsage)
- capacity (AttributeUsage)
- batmobileEngine (PartUsage)
- enginePort (PortUsage)