Spaces:
Sleeping
Sleeping
File size: 8,726 Bytes
24ff0bb 6ef6bfa 24ff0bb 383db3a 24ff0bb dc20d40 24ff0bb 6ef6bfa 24ff0bb ad0de6a 24ff0bb ab600e4 24ff0bb f04248a 323c138 338aa06 383db3a 24ff0bb ad0de6a 24ff0bb ad0de6a f04248a 553569c 383db3a dc20d40 383db3a 24ff0bb dc20d40 6ef6bfa ad0de6a 6ef6bfa ad66892 ad0de6a ad66892 ab600e4 77dedee f04248a 24ff0bb 383db3a 24ff0bb 383db3a 30af434 6ef6bfa 24ff0bb ad66892 24ff0bb 77dedee ab600e4 24ff0bb ad66892 24ff0bb ad66892 f04248a 553569c 323c138 338aa06 24ff0bb 383db3a 24ff0bb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 | import argparse
import os
import logging
from .client import ScribeClient
import json
from dotenv import load_dotenv
dotenv_path = os.path.join(os.path.dirname(__file__), "mcp_app", "env") # relative to cli.py location
load_dotenv(dotenv_path)
def main():
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
parser = argparse.ArgumentParser(description="Scribe Client CLI")
parser.add_argument("--api-call", choices=[
"get-products",
"get-datasets",
"get-policy-results",
"list-attestations",
"get-attestation",
"delete-attestation",
"get-product-vulnerabilities",
"get-latest-attestation",
"query-vulnerabilities",
"query-products",
"query-policy-results",
"query-lineage",
"query-risk",
"query-findings",
"get-dataset-links",
"get-dataset-data",
"get-dataset-tables-dict",
"get-dataset-tables-md",
], help="Which API call to execute")
parser.add_argument("--api-token", required=False, default=os.getenv('SCRIBE_TOKEN'), help="Your API token from ScribeHub integrations page (defaults to SCRIBE_TOKEN environment variable)")
parser.add_argument("--env", default="prod", choices=["prod", "dev", "test", "ci"], help="Which environment to use")
parser.add_argument("--product-name", required=False, help="The name of the product (required for specific API calls)")
parser.add_argument("--attestation-id", required=False, help="The ID of the attestation (required for get-attestation API call)")
parser.add_argument("--query", required=False, help="The query to run on the dataset (required for query commands)")
parser.add_argument("--lineage-graph-file", required=False, help="The file to save the lineage graph to (optional)")
parser.add_argument("--username", required=False, default = os.getenv('SUPERSET_DEV_USERNAME'), help="Superset username (required for Superset API calls)")
parser.add_argument("--password", required=False, default = os.getenv('SUPERSET_DEV_PASSWORD'), help="Superset password (required for Superset API calls)")
parser.add_argument("--mcp", action="store_true", help="Run the MCP FastAPI server (requires [mcp] extras)")
args = parser.parse_args()
if args.mcp:
import traceback
try:
from scribe_python_client.mcp_app.main import run_mcp_server
except Exception as e:
logging.error("FastAPI server not available. Install with: pip install scribe-python-client[mcp]")
traceback.print_exc()
exit(1)
run_mcp_server()
return
if not args.api_token:
logging.error("No API token provided. Please set the SCRIBE_TOKEN environment variable or pass --api-token.")
exit(1)
if args.api_call in ["get-policy-results", "get-product-vulnerabilities", "get-latest-attestation"] and not args.product_name:
logging.error("The --product-name argument is required for the selected API call.")
exit(1)
if args.api_call in ["get-attestation", "delete-attestation"] and not args.attestation_id:
logging.error("The --attestation-id argument is required for the selected API call.")
exit(1)
if args.api_call in ["query-vulnerabilities", "query-products", "query-policy-results", "query-lineage"] and not args.query:
logging.error("The --query argument is required for the selected API call.")
exit(1)
base_url = "https://api.scribesecurity.com"
if args.env != "prod":
base_url = f"https://api.{args.env}.scribesecurity.com"
if args.api_call in ["get-dataset-links", "get-dataset-data", "get-dataset-tables-dict", "get-dataset-tables-md"]:
if not args.username or not args.password:
logging.error("--username and --password are required for Superset table export commands.")
exit(1)
client = ScribeClient(api_token=args.api_token, base_url=base_url, env = args.env, username= args.username, password=args.password)
# lineage_prompt = client.get_dataset_prompt(client.scribe_lineage_dataset)
# print(f"Lineage prompt:\n {lineage_prompt}")
logging.info(f"Executing API call: {args.api_call}")
if args.api_call == "get-products":
print(client.get_products_str())
elif args.api_call == "get-datasets":
print(client.get_datasets())
elif args.api_call == "get-policy-results":
print(client.get_policy_results_str(logical_app=args.product_name))
elif args.api_call == "list-attestations":
print(client.list_attestations())
elif args.api_call == "get-attestation":
print(client.get_attestation(args.attestation_id))
elif args.api_call == "delete-attestation":
success = client.delete_attestation(args.attestation_id)
if success:
print(f"Attestation {args.attestation_id} deleted successfully.")
else:
print(f"Failed to delete attestation {args.attestation_id}.")
elif args.api_call == "get-product-vulnerabilities":
print(client.get_product_vulnerabilities_str(logical_app=args.product_name))
elif args.api_call == "get-latest-attestation":
criteria = {"name": args.product_name}
print(client.get_latest_attestation(criteria=criteria))
elif args.api_call == "query-vulnerabilities":
print(client.query_vulnerabilities(querystr=args.query))
elif args.api_call == "query-products":
print(client.query_products(querystr=args.query))
elif args.api_call == "query-policy-results":
print(client.query_policy_results(querystr=args.query))
elif args.api_call == "query-lineage":
print(client.query_lineage(querystr=args.query))
if args.lineage_graph_file:
client.query_lineage(args.query, graph_filename=args.lineage_graph_file)
# logging.info(f"Lineage graph saved to {args.lineage_graph_file}")
elif args.api_call == "query-risk":
print(client.query_risk(querystr=args.query))
elif args.api_call == "query-findings":
print(client.query_findings(querystr=args.query))
# Get dataset metadata section:
elif args.api_call == "get-dataset-links":
links = client.get_dataset_links()
if links:
print("Dataset Links:")
for link in links:
print(link)
else:
logging.error("No dataset links found.")
result = None
elif args.api_call == "get-dataset-data":
dataset_links = client.get_dataset_links()
if dataset_links:
client.get_dataset_data(dataset_links, output_file="dataset_metadata.csv")
logging.info("Metadata export completed successfully.")
else:
logging.error("No dataset links found.")
result = None
elif args.api_call == "get-dataset-tables-dict":
dataset_links = client.get_dataset_links()
if dataset_links:
client.get_dataset_data(dataset_links, output_file="dataset_metadata.csv")
logging.info("Metadata export completed successfully.")
else:
logging.error("No dataset links found.")
result = None
tables_dict = client.get_dataset_tables_dict()
#Output path is set to docs/dataset_tables.json
output_path = os.path.join("docs", "dataset_tables.json")
with open(output_path, "w", encoding="utf-8") as f:
json.dump(tables_dict, f, indent=2)
logging.info(f"Saved table metadata dictionary to {output_path}")
if result is not None:
print(result)
elif args.api_call == "get-dataset-tables-md":
if not client.jwt_token:
username = input("Enter your Superset username: ")
password = input("Enter your Superset password: ")
client.username = username
client.password = password
if not client.authenticate():
logging.error("Superset login failed.")
exit(1)
dataset_links = client.get_dataset_links()
if dataset_links:
client.get_dataset_data(dataset_links, output_file="dataset_metadata.csv")
md_output = client.get_dataset_tables_md()
#Output path is set to docs/dataset_tables.md
output_path = os.path.join("docs", "dataset_tables.md")
with open(output_path, "w", encoding="utf-8") as f:
f.write(md_output)
logging.info(f"Saved table metadata Markdown to {output_path}")
else:
logging.error("No dataset links found.")
if __name__ == "__main__":
main() |