Skip to main content

PlanDev-CLI

PlanDev-CLI provides a command-line interface and user-extendable Python API for interacting with an instance of PlanDev.

Note: this project is an informal CLI and is not maintained by the MPSA PlanDev team.

Upgrading from Aerie-CLI

Version 2.12.0 renames Aerie-CLI to PlanDev-CLI and supports PlanDev 4.4.0. This release uses the new package, command, and Python API names exclusively.

Use plandev-cli instead of aerie-cli, or python3 -m plandev_cli instead of python3 -m aerie_cli.

Python applications must update their imports and references:

Usage Previous name New name
Python package aerie_cli plandev_cli
Python modules & constructor keywords aerie_client, aerie_host plandev_client, plandev_host
Class name prefix Aerie (e.g., AerieClient) PlanDev (e.g., PlanDevClient)
Host JWT attribute aerie_jwt plandev_jwt
Host version-check method check_aerie_version() check_plandev_version()

Existing legacy host configurations are automatically copied from the old aerie_cli configuration directory when no configuration file exists in the new plandev_cli directory.

Saved authentication sessions are not migrated. After upgrading, reactivate a configuration:

plandev-cli activate

Command expansion is unavailable in this CLI release - previous CLI commands used the deprecated EDSL expansion APIs. Template-based expansion is supported by the PlanDev UI; CLI support is planned for a future release.

Getting Started

This short procedure will get you up and running with the basics of the CLI.

  1. Install/update to Python >= 3.6

  2. Install PlanDev-CLI from Github:

    python3 -m pip install git+https://github.com/NASA-AMMOS/plandev-cli.git@main
    
  3. Configure access to an PlanDev host

    1. If you've been provided a Configuration JSON, reference that file

    2. If you don't have already have a Configuration JSON, copy the following to a JSON file for a local PlanDev deployment (replacing the username with your own):

      [
        {
          "name": "localhost",
          "graphql_url": "http://localhost:8080/v1/graphql",
          "gateway_url": "http://localhost:9000",
          "username": "my_username"
        }
      ]
      
    3. Load either your given configuration(s) or the configuration above into PlanDev-CLI:

      plandev-cli configurations load -i JSON_FILE
      
  4. Activate a configuration to start a session with a PlanDev host:

    ➜  plandev-cli activate
       1) localhost
       Select an option: 1
    
  5. Try out a command to list the plans in PlanDev:

    plandev-cli plans list
    
  6. Use the --help flag on any command to see available subcommands and parameters. For example:

    plandev-cli --help
    ...
    plandev-cli plans --help
    ...
    plandev-cli plans download --help
    

CLI Usage

Setup

PlanDev-CLI uses configurations to define different PlanDev hosts. Define configurations by either loading JSON configurations or manually via the CLI. Configurations persist on a per-user basis and may be shared between installations.

Defining Hosts with a Configuration File

If you have a file of configurations to load, you can use the configurations load command:

plandev-cli configurations load -i JSON_FILE

You can view the configurations you've loaded with the configurations list command:

➜  plandev-cli configurations list
Configuration file location: /Users/<username>/Library/Application Support/plandev_cli/config.json

                                         PlanDev Host Configurations
┏━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━┓
┃ Host Name ┃ GraphQL API URL                  ┃ PlanDev Gateway URL     ┃ Username ┃
┡━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━┩
│ localhost │ http://localhost:8080/v1/graphql │ http://localhost:9000 │          │
└───────────┴──────────────────────────────────┴───────────────────────┴──────────┘

Defining hosts via the CLI

If you haven't been provided a JSON configuration for a host, you can create a configuration by running plandev-cli configurations create and follow the prompts.

Full Specification

Each configuration is stored as JSON object list entry in the configuration file provided with the configurations list command. The full contents of a host configuration are:

Field Description Required
name User-facing name of the host Yes
graphql_url URL of the PlanDev instance's Hasura GraphQL API Yes
gateway_url URL of the PlanDev instance's Gateway Yes
username Username for authentication with PlanDev No
external_auth Specification for external authentication required to reach a PlanDev instance. See Configuring for External Authentication for details No

Sessions and Roles

PlanDev-CLI maintains a persistent "session" with a PlanDev instance so multiple commands can run without needing to re-authenticate. To start a session, use the activate command:

➜  plandev-cli activate
    1) localhost
    ...
    Select an option: 1

PlanDev uses "roles" to adjust what a client is permitted to do. To view the active configuration name and current role, use the status command:

➜  plandev-cli status
Active configuration: localhost
Active role: viewer

The default role is configured by PlanDev. To change the selected role for the active PlanDev-CLI session, use the role command:

➜  plandev-cli role
Active Role: viewer
	1) aerie_admin
	2) user
	3) viewer
Select an option: 1
Changed role to: aerie_admin

At any time, the active session can be closed with the deactivate command.

Commands

Commands are the main functions available via the CLI and are broken down into several levels. For example, the top-level plans command has sub-commands for list, upload, simulate, and more. From any command or sub-command, use the --help flag to learn about what commands are available or what arguments are required.

Help at script level:

plandev-cli --help

Help at command level:

plandev-cli plans --help

Help at sub-command level:

plandev-cli plans download --help

Interactive vs. Non-Interactive

If a command is invoked without the necessary arugments, interactive prompts are provided:

➜  plandev-cli plans download
    Id: 42
    Output: sample-output.json

Alternatively, arguments can be provided using flags:

➜  plandev-cli plans download --id 42 --output sample-output.json

Advanced Topics

Configuring for External Authentication

PlanDev-CLI configurations include a mechanism to authenticate against an external authentication service which may require additional credentials as cookies for accessing PlanDev. PlanDev-CLI will issue a post request with given JSON data to a provided authentication endpoint and persist any returned cookies in a browser-like manner for the remainder of the PlanDev-CLI session.

An external authentication service is configured using the key external_auth in the JSON configuration file as follows:

  {
    "name": "my_host",
    "graphql_url": "https://hostname/v1/graphql",
    "gateway_url": "https://hostname/gateway",
    "username": "my_username",
    "external_auth": {
      "auth_url": "https://auth_service/route",
      "static_post_vars": {
        "username": "my_username"
      },
      "secret_post_vars": [
        "password"
      ]
    }
  }

Here, static_post_vars is an object containing fixed values to include in the post request payload such as usernames and other persistent, non-sensitive fields. secret_post_vars is a list of keys for credentials which may be sensitive or time-varying. The user will be prompted to provide the "secret" values using hidden entry in the terminal when activating a session with external authentication.

In this example, the user would be prompted to enter a value for "password" and, assuming they enter "my_password", the post request JSON would include the following:

{
  "username": "my_username",
  "password": "my_password"
}

Using a Hasura Admin Secret

In some cases, an admin secret may be used to permit otherwise prohibited requests through Hasura (the software behind the PlanDev API). When running a command, the user may add the --hasura-admin-secret flag after the plandev-cli command to use these elevated privileges for the following command.


Python API

Quickstart Guide

Instead of using the CLI for interactive use cases, the underlying classes and methods behind PlanDev-CLI can be invoked directly in Python scripts.

The key constructs are:

  • plandev_cli.plandev_host.PlanDevHost: An abstraction for a PlanDev Host, including methods for authentication and issuing requests to the PlanDev API.
  • plandev_cli.plandev_client.PlanDevClient: A class containing common requests and reusable logic to interact with data in PlanDev.

The following example defines an PlanDevHost using the necessary URLs, authenticates with a command-line prompt for the user's password, and issues a simple request using one of the built-in requests.

from plandev_cli.plandev_client import PlanDevClient
from plandev_cli.plandev_host import PlanDevHost

from getpass import getpass

# These URLs define the PlanDev host
GRAPHQL_URL = "http://myhostname:8080/v1/graphql"
GATEWAY_URL = "http://myhostname:9000"

# User credentials. The password may be omitted on PlanDev instances with authentication disabled
USERNAME = "myusername"
PASSWORD = getpass(prompt='Password: ')

# Define the host and provide user credentials
plandev_host = PlanDevHost(GRAPHQL_URL, GATEWAY_URL)
plandev_host.authenticate(USERNAME, PASSWORD)

# PlanDevClient takes in a host and returns an object to issue requests to that host
client = PlanDevClient(plandev_host)

# Simple example of a request to get an activity plan using the plan ID
plan = client.get_activity_plan_by_id(42)
print(plan.name)

Look through the available methods in the provided PlanDevClient class to find ones that suit your needs.

Adding Methods

If you need to write a custom query, you can extend the PlanDevClient class and add your own method. Access the PlanDev host using the plandev_host property. For example:

# ...

class MyCustomPlanDevClient(PlanDevClient):
    def get_plan_id_by_name(self, plan_name: str) -> int:
        my_query = """
        query GetPlanIdByName($plan_name: String!) {
            plan(where: { name: { _eq: $plan_name } }) {
                id
            }
        }
        """

        # Pass variables for the query as keyword arguments
        resp = self.plandev_host.post_to_graphql(
            my_query,
            plan_name=plan_name
        )
        return resp[0]["id"]

Now, you can use your custom method like any other:

# ...
client = MyCustomPlanDevClient(plandev_host)
plan_id = client.get_plan_id_by_name("my-plan-name")
print(plan_id)

Using the Active CLI Session

If your application will be run by a user who may also be using the CLI, you may reduce the amount of code required to configure an PlanDev host and instead just use the active session. PlanDev-CLI provides a utility to retrieve an PlanDevClient instance from the active CLI session:

from plandev_cli.utils.sessions import get_active_session_client

# client is an instance of `PlanDevClient`
client = get_active_session_client()

# Issue requests like normal
plan = client.get_activity_plan_by_id(...)

Advanced Authentication

If you have needs for authentication (e.g., a custom token system) that aren't provided by PlanDev-CLI, you can use any features supported by the Python requests module's Session class. Instantiate a session object, manipulate/add headers/cookies/SSL certificates/etc. as necessary, and use to instantiate an PlanDevHostSession:

# ...
from requests import Session

my_custom_requests_session = Session()
# Manipulate as necessary
# ...

plandev_host = PlanDevHost(
    GRAPHQL_URL,
    GATEWAY_URL,
    session=my_custom_requests_session
)
plandev_host.authenticate(...)
client = PlanDevClient(plandev_host)

# Use client as normal

Contributing

Contributor Installation

The recommended develper installation method is in a virutual environment with an editatable install via Pip.

See this primer or virtual environments to get set up. A quick and easy method is using Python's native venv package from the root of the PlanDev-CLI repo:

python3 -m venv venv
source venv/bin/activate

Then, install PlanDev-CLI in editable mode via Pip:

python3 -m pip install -e .

Now, your installation of PlanDev-CLI will update as you make changes to the source code.

Dependency Management

Dependencies are currently managed via Poetry. For more information on dependency and project management, see the poetry docs.

Testing

PlanDev-CLI has unit tests and integration tests built with the pytest library.

Unit Tests

Unit tests can be run anytime and reference local test files. test_plandev_client.py is where unit tests are added to exercise particular methods of the PlanDevClient class using mocked PlanDev API responses.

Run the unit tests using pytest from the tests directory:

cd tests
python3 -m pytest unit_tests

Integration Tests

A separate suite of tests is designed to validate CLI functionality against a local instance of PlanDev. See the integration testing documentation for details.

The integration tests are based on Typer testing documentation found here.

Releases

PlanDev-CLI generally follows the gitflow workflow model for managing releases:

  • Features are merged to the develop branch.
  • Release branches are made from develop and merge in main for testing.
  • Releases are made from the tip of the main branch.
  • Hotfix branches can be made from main to resolve bugs without needing to incorporate new features.

Version numbers are managed using semantic versioning in pyproject.toml:

  • The version tag on develop is fixed at 0.0.0-dev0
  • Release versions are incremented on release branches before being merged to main.

The full workflow for releasing a new version of PlanDev-CLI:

  • Make a release branch from develop
  • Merge main into the release branch
  • Commit a version increment in pyproject.toml
  • Open a PR to merge the release branch into main and verify CI passes
  • Merge the PR and tag a release on main

Metadata

Release files for plandev-cli 2.12.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for plandev-cli 2.12.0
File Size Uploaded Provenance Actions
plandev_cli-2.12.0.tar.gz 50.6 kB With provenance Details for plandev_cli-2.12.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for plandev-cli 2.12.0
File Interpreter ABI Platform Actions
plandev_cli-2.12.0-py3-none-any.whl Python 3 none any Details for plandev_cli-2.12.0-py3-none-any.whl

Total release size: 105.8 kB

Release files / plandev_cli-2.12.0.tar.gz

Download URL plandev_cli-2.12.0.tar.gz
Size 50.6 kB
Tags Source
SHA-256 checksum
How to use checksums
b840eb34cd3598391ff33ef2311c6107984407bef980b956e5d48fd07beef793
BLAKE2b-256 checksum
How to use checksums
4005948d364e84608bff99d90136f9e6ab87bf421ca5f83b3fb709ca76bc6324
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

Release files / plandev_cli-2.12.0-py3-none-any.whl

Download URL plandev_cli-2.12.0-py3-none-any.whl
Size 55.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ff530c9211cb12996665407e952bf19b0c1d3a76a0561be3865aaa5ea0d3f09c
BLAKE2b-256 checksum
How to use checksums
fe282c23de147176a5e6161c513a4cc36a4877cf027491243814b0d84b928152
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

Security for plandev-cli 2.12.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for plandev_cli-2.12.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 9, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

2.12.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page