Sleep Tutorial
The sleep command will have one argument which will be how long to sleep for.
import asyncio
import logging
from textual_shell.command import Command, CommandNode
from textual_shell.job import Job
class Sleep(Command):
"""Command to sleep for x seconds."""
DEFINITION = {
'sleep': CommandNode(
name='sleep',
description='Sleep for x seconds'
)
}
First things first, import the Command, CommandNode, and Job from their respective modules. Then define a new Sleep class that extends the Command base class. Afterwards, write the DEFINITION for the command. The DEFINITION is a dictionary where the keys are the name of the nodes and the values are CommandNodes.
import asyncio
import logging
from textual_shell.command import Command, CommandNode
from textual_shell.job import Job
class SleepSeconds(Job):
pass
class Sleep(Command):
"""
Command to sleep for x seconds.
Examples:
sleep 10
"""
DEFINITION = {
'sleep': CommandNode(
name='sleep',
description='Sleep for x seconds'
)
}
def create_job(self, *args) -> SleepSeconds:
"""
Create a SleepJob to execute the asyncio.sleep()
Returns:
job (SleepSeconds): A job that will sleep for x seconds.
"""
# Simple cmdline validation.
if len(args) != 1:
self.shell.notify(
message='Invalid Arguments',
title='Command: sleep',
severity='error'
)
return
elif not args[0].isdigit():
self.shell.notify(
message='Argument should be a number',
title='Command: sleep',
severity='error'
)
return
return SleepSeconds(
shell=self.shell,
cmd=self.name,
seconds=args[0]
)
Next lets define the SleepSeconds class that extends the Job base class. This will be the object that is created by the Sleep command and will contain the asyncio.Task object. Lets also implement some commandline validation. The command only takes a single argument and that argument should be a number. If those conditions are not met then send an error notification and return. Note the passing of the self.shell and self.name as parameters to the SleepSeconds Job. The self.shell is required so the job can send messages to the app.
import asyncio
import logging
from textual_shell.command import Command, CommandNode
from textual_shell.job import Job
class SleepSeconds(Job):
"""
A job that will sleep for x seconds.
Args:
seconds (str): The amount of seconds to sleep for.
"""
def __init__(self, seconds: str, *args, **kwargs) -> None:
super().__init__(*args, **kwargs) # IMPORTANT: Make sure to call the super.
self.seconds = int(seconds)
async def execute(self):
"""Use asyncio.sleep to sleep in the background."""
self.running() # set the status to running
self.send_log(
msg=f'{self.id} - Sleeping for {self.seconds} seconds.',
severity=logging.INFO
)
await asyncio.sleep(self.seconds)
self.send_log(
msg=f'{self.id} - Slept for {self.seconds} seconds.',
severity=logging.INFO
)
self.completed() # set the status to completed.
class Sleep(Command):
"""
Command to sleep for x seconds.
Examples:
sleep 10
"""
DEFINITION = {
'sleep': CommandNode(
name='sleep',
description='Sleep for x seconds'
)
}
def create_job(self, *args) -> SleepSeconds:
"""
Create a SleepJob to execute the asyncio.sleep()
Returns:
job (SleepSeconds): A job that will sleep for x seconds.
"""
# Simple cmdline validation.
if len(args) != 1:
self.shell.notify(
message='Invalid Arguments',
title='Command: sleep',
severity='error'
)
return
elif not args[0].isdigit():
self.shell.notify(
message='Argument should be a number',
title='Command: sleep',
severity='error'
)
return
return SleepSeconds(
shell=self.shell,
cmd=self.name,
seconds=args[0]
)
Wrap Up
That concludes the implementation of a basic sleep command. The create_job method should return a job or None if the job creation failed. The timer tutorial is a little more advanced as we will look at screen management within a job.