Skip to content

Commit

Permalink
CTX-6257: coretex task run entrypoint.py command improvements regardi…
Browse files Browse the repository at this point in the history
…ng task acceptance criteria.
  • Loading branch information
Bogdan Tintor committed Aug 26, 2024
1 parent 70ce25d commit 2a9306d
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 21 deletions.
6 changes: 5 additions & 1 deletion coretex/cli/commands/login.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import click

from ..modules import user, ui
from ...configuration import UserConfiguration, InvalidConfiguration, ConfigurationNotFound
from ...configuration import UserConfiguration, InvalidConfiguration, ConfigurationNotFound, utils


@click.command()
Expand All @@ -38,5 +38,9 @@ def login() -> None:

ui.stdEcho("Please enter your credentials:")
userConfig = user.configUser()

initialData = utils.fetchInitialData()
userConfig.frontendUrl = initialData.get("frontend_url", "app.coretex.ai/")

userConfig.save()
ui.successEcho(f"User {userConfig.username} successfully logged in.")
2 changes: 1 addition & 1 deletion coretex/cli/commands/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def create(name: str, path: str, project: Optional[str], accuracy: float) -> Non
model.upload(path)

ui.successEcho(f"Model \"{model.name}\" created successfully")
ui.stdEcho(f"A new model has been created. You can open it by clicking on this URL {ui.outputUrl(model.entityUrl())}.")
ui.stdEcho(f"A new model has been created. You can open it by clicking on this URL {ui.outputUrl(userConfig.frontendUrl, model.entityUrl())}.")


@click.group()
Expand Down
8 changes: 6 additions & 2 deletions coretex/cli/commands/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
@click.option("--type", "-t", "projectType", type = int, help = "Project type")
@click.option("--description", "-d", type = str, help = "Project description")
def create(name: Optional[str], projectType: Optional[int], description: Optional[str]) -> None:
project = project_utils.createProject(name, projectType, description)
userConfig = UserConfiguration.load()
project = project_utils.createProject(userConfig.frontendUrl, name, projectType, description)

selectNewProject = ui.clickPrompt("Do you want to select the new project as default? (Y/n)", type = bool, default = True)
if selectNewProject:
Expand Down Expand Up @@ -86,7 +86,11 @@ def select(name: str) -> None:
userConfig.selectProject(project.id)
except ValueError:
ui.errorEcho(f"Project \"{name}\" not found.")
project = project_utils.promptProjectCreate("Do you want to create a project with that name?", name)
project = project_utils.promptProjectCreate(
"Do you want to create a project with that name?",
name,
userConfig.frontendUrl
)
if project is None:
return

Expand Down
17 changes: 11 additions & 6 deletions coretex/cli/commands/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from typing import Optional

import click
import webbrowser

from ..modules import ui
from ..modules.project_utils import getProject
Expand All @@ -26,7 +27,7 @@
from ..modules.project_utils import getProject
from ..._folder_manager import folder_manager
from ..._task import TaskRunWorker, executeRunLocally, readTaskConfig, runLogger
from ...configuration import UserConfiguration, NodeConfiguration
from ...configuration import UserConfiguration
from ...entities import TaskRun, TaskRunStatus
from ...resources import PYTHON_ENTRY_POINT_PATH
from ..._task import TaskRunWorker, executeRunLocally, readTaskConfig, runLogger
Expand Down Expand Up @@ -60,10 +61,10 @@ def run(path: str, name: Optional[str], description: Optional[str], snapshot: bo

ui.stdEcho(
"Project info: "
f"\tName: {selectedProject.name}"
f"\tName: {selectedProject.projectType.name}"
f"\tName: {selectedProject.description}"
f"\tName: {selectedProject.createdOn}"
f"\n\tName: {selectedProject.name}"
f"\n\tProject type: {selectedProject.projectType.name}"
f"\n\tDescription: {selectedProject.description}"
f"\n\tCreated on: {selectedProject.createdOn}"
)

taskRun: TaskRun = TaskRun.runLocal(
Expand All @@ -75,7 +76,11 @@ def run(path: str, name: Optional[str], description: Optional[str], snapshot: bo
entryPoint = path
)

ui.stdEcho(f"Task Run successfully started. You can open it by clicking on this URL {ui.outputUrl(taskRun.entityUrl())}.")
ui.stdEcho(
"Task Run successfully started. "
f"You can open it by clicking on this URL {ui.outputUrl(userConfig.frontendUrl, taskRun.entityUrl())}."
)
webbrowser.open(f"{userConfig.frontendUrl}/{taskRun.entityUrl()}")

taskRun.updateStatus(TaskRunStatus.preparingToStart)

Expand Down
28 changes: 21 additions & 7 deletions coretex/cli/modules/project_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def selectProjectVisibility() -> ProjectVisibility:
return selectedProjectVisibility


def promptProjectCreate(message: str, name: str) -> Optional[Project]:
def promptProjectCreate(message: str, name: str, frontendUrl: str) -> Optional[Project]:
if not click.confirm(message, default = True):
return None

Expand All @@ -49,7 +49,10 @@ def promptProjectCreate(message: str, name: str) -> Optional[Project]:
try:
project = Project.createProject(name, selectedProjectType)
ui.successEcho(f"Project \"{name}\" created successfully.")
ui.stdEcho(f"A new Project has been created. You can open it by clicking on this URL {ui.outputUrl(project.entityUrl())}.")
ui.stdEcho(
"A new Project has been created. "
f"You can open it by clicking on this URL {ui.outputUrl(frontendUrl, project.entityUrl())}."
)
return project
except NetworkRequestError as ex:
logging.getLogger("cli").debug(ex, exc_info = ex)
Expand All @@ -66,7 +69,11 @@ def promptProjectSelect(userConfig: UserConfiguration) -> Optional[Project]:
userConfig.selectProject(project.id)
except ValueError:
ui.errorEcho(f"Project \"{name}\" not found.")
newProject = promptProjectCreate("Do you want to create a project with that name?", name)
newProject = promptProjectCreate(
"Do you want to create a project with that name?",
name,
userConfig.frontendUrl
)
if newProject is None:
return None

Expand All @@ -75,7 +82,7 @@ def promptProjectSelect(userConfig: UserConfiguration) -> Optional[Project]:
return project


def createProject(name: Optional[str] = None, projectType: Optional[int] = None, description: Optional[str] = None) -> Project:
def createProject(frontendUrl: str, name: Optional[str] = None, projectType: Optional[int] = None, description: Optional[str] = None) -> Project:
if name is None:
name = ui.clickPrompt("Please enter name of the project you want to create", type = str)

Expand All @@ -90,7 +97,10 @@ def createProject(name: Optional[str] = None, projectType: Optional[int] = None,
try:
project = Project.createProject(name, projectType, description = description)
ui.successEcho(f"Project \"{name}\" created successfully.")
ui.stdEcho(f"A new Project has been created. You can open it by clicking on this URL {ui.outputUrl(project.entityUrl())}.")
ui.stdEcho(
"A new Project has been created. "
f"You can open it by clicking on this URL {ui.outputUrl(frontendUrl, project.entityUrl())}."
)
return project
except NetworkRequestError as ex:
logging.getLogger("cli").debug(ex, exc_info = ex)
Expand All @@ -104,7 +114,11 @@ def getProject(name: Optional[str], userConfig: UserConfiguration) -> Optional[P
return Project.fetchOne(name = name)
except:
if projectId is None:
return promptProjectCreate("Project not found. Do you want to create a new Project with that name?", name)
return promptProjectCreate(
"Project not found. Do you want to create a new Project with that name?",
name,
userConfig.frontendUrl
)

return Project.fetchById(projectId)

Expand All @@ -116,6 +130,6 @@ def getProject(name: Optional[str], userConfig: UserConfiguration) -> Optional[P
if not click.confirm("Would you like to create a new Project?", default = True):
return None

return createProject(name)
return createProject(userConfig.frontendUrl, name)

return Project.fetchById(projectId)
4 changes: 2 additions & 2 deletions coretex/cli/modules/ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ def previewNodeConfig(nodeConfig: NodeConfiguration) -> None:
stdEcho(tabulate(table))


def outputUrl(entityUrl: str) -> str:
return ("\033[4m" + f"https://app.coretex.ai/{entityUrl}" + "\033[0m")
def outputUrl(baseUrl: str, entityUrl: str) -> str:
return ("\033[4m" + f"{baseUrl}/{entityUrl}" + "\033[0m")


def stdEcho(text: str) -> None:
Expand Down
8 changes: 8 additions & 0 deletions coretex/configuration/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ def projectId(self) -> Optional[int]:
def projectId(self, value: Optional[int]) -> None:
self._raw["projectId"] = value

@property
def frontendUrl(self) -> str:
return self.getValue("frontendUrl", str, default = "app.coretex.ai")

@frontendUrl.setter
def frontendUrl(self, value: Optional[str]) -> None:
self._raw["frontendUrl"] = value

def _isConfigValid(self) -> Tuple[bool, List[str]]:
isValid = True
errorMessages = []
Expand Down
11 changes: 10 additions & 1 deletion coretex/configuration/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

from typing import Optional, Tuple, Any
from typing import Optional, Tuple, Any, Dict

from . import config_defaults
from ..networking import networkManager, NetworkRequestError
Expand Down Expand Up @@ -132,3 +132,12 @@ def fetchNodeId(name: str) -> int:
raise TypeError(f"Invalid \"id\" type {type(id)}. Expected: \"int\"")

return id


def fetchInitialData() -> Dict[str, Any]:
response = networkManager.get("user/initial-data")

if response.hasFailed():
raise NetworkRequestError(response, "Failed to fetch user's initial data.")

return response.getJson(dict)
4 changes: 3 additions & 1 deletion coretex/entities/task_run/task_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class TaskRun(NetworkObject, Generic[DatasetType]):
useCachedEnv: bool
executionType: ExecutionType
metrics: List[Metric]
workflowRunId: int

def __init__(self) -> None:
super(TaskRun, self).__init__()
Expand Down Expand Up @@ -164,6 +165,7 @@ def _keyDescriptors(cls) -> Dict[str, KeyDescriptor]:
descriptors["taskId"] = KeyDescriptor("sub_project_id")
descriptors["taskName"] = KeyDescriptor("sub_project_name")
descriptors["executionType"] = KeyDescriptor("execution_type", ExecutionType)
descriptors["workflowRunId"] = KeyDescriptor("pipeline_run_id")

# private properties of the object should not be encoded
descriptors["__parameters"] = KeyDescriptor(isEncodable = False)
Expand All @@ -177,7 +179,7 @@ def _endpoint(cls) -> str:

@override
def entityUrl(self) -> str:
return f"workflow-run?id={self.id}"
return f"workflow-run?id={self.workflowRunId}"

def onDecode(self) -> None:
super().onDecode()
Expand Down

0 comments on commit 2a9306d

Please sign in to comment.