Skip to content

Commit

Permalink
fix the history option
Browse files Browse the repository at this point in the history
  • Loading branch information
ZihengSun committed Jun 30, 2024
1 parent 34f9f94 commit fbad1a4
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 55 deletions.
4 changes: 2 additions & 2 deletions pygeoweaver/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,15 @@ def start_command(force_download, force_restart):
"""
Start the Geoweaver application.
"""
start(force_download=force_download, force_restart=force_restart)
start(force_download=force_download, force_restart=force_restart, exit_on_finish=True)


@geoweaver.command("stop")
def stop_command():
"""
Start the Geoweaver application.
"""
stop()
stop(exit_on_finish=True)

@geoweaver.command("show")
@click.option('--geoweaver-url', default=GEOWEAVER_DEFAULT_ENDPOINT_URL, help='Geoweaver URL (default is GEOWEAVER_DEFAULT_ENDPOINT_URL)')
Expand Down
152 changes: 128 additions & 24 deletions pygeoweaver/commands/pgw_history.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,99 @@
import http
import json
import logging
import subprocess
import traceback
from urllib.parse import urlencode, urlparse

import click
import pandas as pd
import requests
from tabulate import tabulate

from pygeoweaver.constants import *
from pygeoweaver.server import check_geoweaver_status, start
from pygeoweaver.utils import (
download_geoweaver_jar,
get_geoweaver_jar_path,
get_java_bin_path,
get_root_dir,
get_spinner,
is_interactive,
)

logger = logging.getLogger(__name__)


def display_response_table(response_json):
"""
Convert the response JSON into a table format and display it.
Args:
response_json (str or dict): The JSON response to display.
"""
if isinstance(response_json, str):
data = json.loads(response_json)
else:
data = response_json

# Convert data into a DataFrame for better visualization
df = pd.DataFrame([data])

# Check if running in Jupyter
if is_interactive():
from IPython.display import display
display(df)
else:
# Use tabulate for terminal display
table = tabulate(df, headers='keys', tablefmt='psql')
print(table)



def show_history(history_id):
"""
Workflow and process history uses the same method to check
History uses the same method to check
"""
if not history_id:
raise RuntimeError("history id is missing")
download_geoweaver_jar()
subprocess.run(
[get_java_bin_path(), "-jar", get_geoweaver_jar_path(), "history", history_id],
cwd=f"{get_root_dir()}/",
)

try:
if not check_geoweaver_status():
start()

log_url = f"{GEOWEAVER_DEFAULT_ENDPOINT_URL}/web/log"
json_data = f"type=process&id={history_id}"
headers = {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
response = requests.post(log_url, headers=headers, data=json_data)

if response.status_code == 200:
try:
display_response_table(response.json())
except requests.exceptions.JSONDecodeError:
raise ValueError('Response is not in JSON format:', response.text)
else:
raise ValueError(f'POST request failed with status code {response.text}')
except Exception as e:
with get_spinner(text=f'Get workflow history...', spinner='dots'):
logger.error(e)
traceback_str = traceback.format_exc()
print(f"Error occurred: {str(e)}")
print(f"Traceback:\n{traceback_str}")

download_geoweaver_jar()
process = subprocess.run(
[get_java_bin_path(), "-jar", get_geoweaver_jar_path(), "history", history_id],
cwd=f"{get_root_dir()}/",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)

print(process.stdout)
if process.stderr:
print("=== Error ===")
print(process.stderr)
logger.error(process.stderr)


def get_process_history(process_id):
Expand All @@ -32,22 +103,43 @@ def get_process_history(process_id):
"""
if not process_id:
raise Exception("please pass `process_id` as a parameter to the function.")
download_geoweaver_jar()
try:
print("why it is still here")
if check_geoweaver_status():
start(exit_on_finish=False)
print("why it is still here")

json_data = f"type=process&id={process_id}"
print(json_data)
headers = {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
r = requests.post(
f"{GEOWEAVER_DEFAULT_ENDPOINT_URL}/web/logs",
data={"type": "process", "id": process_id},
).json()
df = pd.DataFrame(r)
df["history_begin_time"] = pd.to_datetime(df["history_begin_time"], unit="ms")
df["history_end_time"] = pd.to_datetime(df["history_end_time"], unit="ms")
return df
except Exception as e:
subprocess.run(
f"{get_java_bin_path()} -jar {get_geoweaver_jar_path()} process-history {process_id}",
cwd=f"{get_root_dir()}/",
shell=True,
data=json_data,
headers=headers,
)
print("r.text = ", r.text)
if r.status_code == 200:
try:
display_response_table(r.json())
except requests.exceptions.JSONDecodeError:
raise ValueError('Response is not in JSON format:', r.text)
else:
raise ValueError(f'POST request failed with status code {r.text}')
except Exception as e:
with get_spinner(text=f'Get workflow history...', spinner='dots'):
process = subprocess.run(
f"{get_java_bin_path()} -jar {get_geoweaver_jar_path()} process-history {process_id}",
cwd=f"{get_root_dir()}/",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True
)

print(process.stdout)
if process.stderr:
print("=== Error ===")
print(process.stderr)
logger.error(process.stderr)


def get_workflow_history(workflow_id):
Expand All @@ -58,20 +150,32 @@ def get_workflow_history(workflow_id):
if not workflow_id:
raise Exception("please pass `workflow_id` as a parameter to the function.")
try:
if check_geoweaver_status():
start()
r = requests.post(
f"{GEOWEAVER_DEFAULT_ENDPOINT_URL}/web/logs",
data={"type": "workflow", "id": workflow_id},
).json()
df = pd.DataFrame(r)
df["history_begin_time"] = pd.to_datetime(df["history_begin_time"], unit="ms")
df["history_end_time"] = pd.to_datetime(df["history_end_time"], unit="ms")
return df
if is_interactive():
return df
else:
print(df)
except Exception as e:
subprocess.run(
f"{get_java_bin_path()} -jar {get_geoweaver_jar_path()} workflow-history {workflow_id}",
shell=True,
cwd=f"{get_root_dir()}/",
)
with get_spinner(text=f'Get workflow history via slow CLI...', spinner='dots'):
process = subprocess.run(
f"{get_java_bin_path()} -jar {get_geoweaver_jar_path()} workflow-history {workflow_id}",
stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True,
cwd=f"{get_root_dir()}/",
)

print(process.stdout)
if process.stderr:
print("=== Error ===")
print(process.stderr)
logger.error(process.stderr)


def save_history(code: str = None, status: str = None, log_output: str = None, ):
Expand Down
6 changes: 5 additions & 1 deletion pygeoweaver/log_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ def setup_logging():
# Ensure the directory for the log file exists, create if not
log_dir = os.path.dirname(log_file)
os.makedirs(log_dir, exist_ok=True)
with open('logging.ini', 'rt') as f:
# Get the absolute path to the logging.ini file
logging_ini_path = os.path.abspath('logging.ini')

# Open the logging.ini file
with open(logging_ini_path, 'rt') as f:
config_str = f.read()
config_str = config_str.replace('%(log_file)s', os.path.expanduser(log_file))

Expand Down
45 changes: 21 additions & 24 deletions pygeoweaver/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def check_geoweaver_status() -> bool:
raise ValueError(err_msg)


def start_on_windows():
def start_on_windows(force_restart=False, force_download=False, exit_on_finish=True):

with get_spinner(text=f'Stop running Geoweaver if any...', spinner='dots'):
subprocess.run(["taskkill", "/f", "/im", "geoweaver.exe"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
Expand Down Expand Up @@ -103,13 +103,15 @@ def start_on_windows():
with open(log_file, "r") as f:
print(f.read())
print("Success: Geoweaver is up")
safe_exit(0)
if exit_on_finish:
safe_exit(0)
except Exception as e:
# print(f"Error occurred during request: {e}")
continue

print("Error: Geoweaver is not up")
safe_exit(1)
if exit_on_finish:
safe_exit(1)


def stop_on_windows():
Expand Down Expand Up @@ -137,18 +139,17 @@ def check_java_exists():
return None


def start_on_mac_linux(force_restart=True):

def start_on_mac_linux(force_restart: bool=False, force_download: bool=False, exit_on_finish: bool=False):
if force_restart:
# First stop any existing Geoweaver
stop_on_mac_linux()
stop_on_mac_linux(exit_on_finish=exit_on_finish)


# Checking Java
java_path = check_java_exists()
if java_path is None:
print("Java not found. Exiting...")
safe_exit(1)
if exit_on_finish:
safe_exit(1)

with get_spinner(text=f'Starting Geoweaver...', spinner='dots'):
# Start Geoweaver
Expand Down Expand Up @@ -178,13 +179,15 @@ def start_on_mac_linux(force_restart=True):

if counter == max_counter:
print("Error: Geoweaver is not up")
safe_exit(1)
if exit_on_finish:
safe_exit(1)
else:
print("Success: Geoweaver is up")
safe_exit(0)
if exit_on_finish:
safe_exit(0)


def stop_on_mac_linux() -> int:
def stop_on_mac_linux(exit_on_finish: bool=False) -> int:
with get_spinner(text=f'Stopping Geoweaver...', spinner='dots'):
# Stop running Geoweaver if any
logger.info("Stop running Geoweaver if any..")
Expand All @@ -204,32 +207,26 @@ def stop_on_mac_linux() -> int:
return 1


def start(force_download=False, force_restart=False):
def start(force_download=False, force_restart=False, exit_on_finish=True):
download_geoweaver_jar(overwrite=force_download)
check_java()

if check_os() == 3:
logger.debug(f"Detected Windows, running start python script..")
start_on_windows(force_restart)
start_on_windows(force_restart=force_restart, force_download=force_download, exit_on_finish=exit_on_finish)
else:
logger.debug(f"Detected Linux/MacOs, running start python script..")
start_on_mac_linux(force_restart)
# subprocess.run(
# [f"{get_module_absolute_path()}/start.sh"], cwd=f"{get_root_dir()}/"
# )
start_on_mac_linux(force_restart=force_restart, force_download=force_download, exit_on_finish=exit_on_finish)


def stop():
def stop(exit_on_finish: bool=False):
check_java()
if check_os() == 3:
stop_on_windows()
else:
# subprocess.run(
# [f"{get_module_absolute_path()}/stop.sh"],
# cwd=f"{get_root_dir()}/",
# shell=True,
# )
safe_exit(stop_on_mac_linux())
exit_code = stop_on_mac_linux()
if exit_on_finish:
safe_exit(exit_code)


def show(geoweaver_url=GEOWEAVER_DEFAULT_ENDPOINT_URL):
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ dependencies = [
"pandas",
"halo",
"pydantic",
"tabulate",
]

[project.urls]
Expand Down
8 changes: 4 additions & 4 deletions test/test_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ def test_server_start_stop(self):
200,
f"Failed to access URL: {GEOWEAVER_DEFAULT_ENDPOINT_URL}",
)
stop()
stop(exit_on_finish=False)
with self.assertRaises(requests.exceptions.ConnectionError):
response = requests.get(GEOWEAVER_DEFAULT_ENDPOINT_URL)

stop() # stop again should have no issue
stop(exit_on_finish=False) # stop again should have no issue

def test_windows(self):
with patch("pygeoweaver.server.checkOS") as mock_checkos:
mock_checkos.return_value = 3
with self.assertRaises(RuntimeError):
start()
start(exit_on_finish=False)
with self.assertRaises(RuntimeError):
stop()
stop(exit_on_finish=False)

def test_show_gui(self):
with patch("pygeoweaver.webbrowser.open") as mock_browser_open:
Expand Down

0 comments on commit fbad1a4

Please sign in to comment.