Wrapper Classes¶
This section describe the three wrapper classes that are provided by this Python package. In most cases, you should be able to just grab one of them and implement a few callbacks or overrides some methods in your subclasses to interact with the Austin binary.
If you want to make your own implementation of the wrapper, the
austin.BaseAustin
abstract base class can provide you with a good
starting point.
Note
For the wrappers to work as expected, the Austin binary needs to be locatable from the following sources, in the given order
current working directory;
the
AUSTINPATH
environment variable which gives the path to the folder that contains the Austin binary;the
.austinrc
TOML configuration file in the user’s home folder, e.g.~/.austinrc
on Linux (see below);the
PATH
environment variable.
The Abstract Austin Base Class¶
-
class
austin.
BaseAustin
(sample_callback=None, ready_callback=None, terminate_callback=None)¶ Base Austin class.
Defines the general API that abstract Austin as an external process. Subclasses should implement the
start()
method and either define theon_sample_received()
method or pass it via the constructor. Additionally, theon_ready()
and theon_terminate()
methods can be overridden or passed via the constructor to catch the corresponding events. Austin is considered to be ready when the first sample is received; it is considered to have terminated when the process has terminated gracefully.If an error was encountered, the
AustinError
exception is thrown.-
BINARY
= 'austin'¶
-
BINARY_VERSION
= (3, 0, 0)¶
-
binary_path
¶ Discover the path of the Austin binary.
Lookup order is: - current working directory -
AUSTINPATH
variable -~/.austinrc
file -PATH
variable.
-
check_exit
(rcode, stderr)¶ Check Austin exit status.
- Return type
None
-
check_version
()¶ Check for the minimum Austin binary version.
- Return type
None
-
get_child_process
()¶ Get the child process.
Return an instalce of
psutil.Process
representing the (main) process being profiled by Austin at the OS level.- Return type
Process
-
get_command_line
()¶ Get the inferred command line.
Return the command line of the (main) process that is being profiled by Austin.
- Return type
Optional
[str
]
-
get_process
()¶ Get the underlying Austin process.
Return an instance of
psuitl.Process
that can be used to control the underlying Austin process at the OS level.- Return type
Process
-
is_running
()¶ Determine whether Austin is running.
- Return type
bool
-
on_ready
(process, child_process, command_line, data=None)¶ Ready event callback.
Implement to get notified when Austin has successfully started or attached the Python process to profile and the first sample has been produced. This callback receives the Austin process and it’s (main) profiled process as instances of
psutil.Process
, along with the command line of the latter.- Return type
Any
-
on_terminate
(stats)¶ Terminate event callback.
Implement to be notified when Austin has terminated gracefully. The callback accepts an argument that will receive the global statistics.
- Return type
Any
-
property
python_version
¶ The version of the detected Python interpreter.
- Return type
Tuple
[int
,int
,int
]
-
abstract
start
(args=None)¶ Start Austin.
Every subclass should implement this method and ensure that it spawns a new Austin process.
- Return type
Any
-
submit_sample
(data)¶ Submit a sample to the sample callback.
This method takes care of converting the raw binary data retrieved from Austin into a Python string.
- Return type
None
-
terminate
(wait=False)¶ Terminate Austin.
Stop the underlying Austin process by sending a termination signal.
- Return type
None
-
property
version
¶ Austin version.
- Return type
Tuple
[int
,int
,int
]
-
All the wrappers documented in this section are subclasses of the
austin.BaseAustin
class. The purpose is to set a common base API while
also providing some convenience methods that you are likely to need, so that
you don’t have to implement them yourself.
The start
method¶
The general idea is to subclass austin.BaseAustin
and subclass the
austin.BaseAustin.start()
method with the logic required to start the
Austin binary in the background. By default, Austin’s binary is named
austin
, and you can refer to it with BaseAustin.BINARY
. Hence, if you
were to start Austin in an asyncio fashion, your start method would be a
coroutine starting with:
async def start(self, args: List[str] = []) -> None:
try:
self.proc = await asyncio.create_subprocess_exec(
self.BINARY,
*(args or sys.argv[1:]),
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
except FileNotFoundError:
raise AustinError("Austin executable not found.")
You should use the optional args
argument to pass in the command-line
arguments to pass to the Austin binary, as done in the above example.
Note
For the wrappers to work as expected, the Austin binary specified by the
BINARY
class attribute needs to be on the PATH
environment variable
or they will fail to start. Of course, this value can be overridden by
sub-classes so that this behaviour can be adjusted according to your needs.
The callbacks¶
The other requirement for making a subclass of austin.BaseAustin
concrete is the implementation of the on_sample_received
callback. This
can either be a class method, or passed via the sample_callback
argument
to the constructor of the subclass. This callback function must take a single
argument of type str
, which holds the raw text of a sample collected by
Austin.
There are other two recommended callbacks that you might want to implement:
austin.BaseAustin.on_ready()
and austin.BaseAustin.on_terminate()
.
See the class documentation below for more details.
The Simple Austin Wrapper¶
-
class
austin.simple.
SimpleAustin
(sample_callback=None, ready_callback=None, terminate_callback=None)¶ Bases:
austin.BaseAustin
Simple implementation of Austin.
This is the simplest way to start Austin from Python if you do not need to carry out other operation in parallel. Calling
start()
returns only once Austin has terminated.Example:
class EchoSimpleAustin(SimpleAustin): def on_ready(self, process, child_process, command_line): print(f"Austin PID: {process.pid}") print(f"Python PID: {child_process.pid}") print(f"Command Line: {command_line}") def on_sample_received(self, line): print(line) def on_terminate(self, data): print(data) try: austin = EchoSimpleAustin() austin.start(["-i", "10000"], ["python3", "myscript.py"]) except KeyboardInterrupt: pass
-
start
(args=None)¶ Start the Austin process.
- Return type
None
-
The austin.simple.SimpleAustin
wrapper is for simple applications that
do not require any sort of concurrency or (thread-based) parallelism. For
example, your application does not involve a user interface or asynchronous I/O.
The example above shows you how to make a simple echo Austin application that
effectively acts like the underlying Austin binary. The on_sample_received
is indeed echoing back all the samples that it receives
The asyncio
-based Austin Wrapper¶
-
class
austin.aio.
AsyncAustin
(sample_callback=None, ready_callback=None, terminate_callback=None)¶ Bases:
austin.BaseAustin
Asynchronous implementation of Austin.
Implements an
asyncio
API for Austin so that it can be used alongside other asynchronous tasks.The following example shows how to make a simple asynchronous echo implementation of Austin that behaves exactly just like Austin.
Example:
class EchoAsyncAustin(AsyncAustin): def on_ready(self, process, child_process, command_line): print(f"Austin PID: {process.pid}") print(f"Python PID: {child_process.pid}") print(f"Command Line: {command_line}") def on_sample_received(self, line): print(line) def on_terminate(self, data): print(data) if sys.platform == "win32": asyncio.set_event_loop(asyncio.ProactorEventLoop()) try: austin = EchoAsyncAustin() asyncio.get_event_loop().run_until_complete( austin.start(["-i", "10000", "python3", "myscript.py"]) ) except (KeyboardInterrupt, asyncio.CancelledError): pass
-
async
start
(args=None)¶ Create the start coroutine.
Use with the
asyncio
event loop.- Return type
None
-
async
This wrapper implements an asyncio
-based API around Austin. The start
method is, in fact, a coroutine that can be schedule with any asyncio
event loops.
The example above shows how to implement the same echo example of the simple case using this wrapper.
The Thread-based Austin Wrapper¶
-
class
austin.threads.
ThreadedAustin
(*args, **kwargs)¶ Bases:
austin.simple.SimpleAustin
Thread-based implementation of Austin.
Implements a
threading
API for Austin so that it can be used alongside other threads.The following example shows how to make a simple threaded echo implementation of Austin that behaves exactly just like Austin.
Example:
class EchoThreadedAustin(ThreadedAustin): def on_ready(self, process, child_process, command_line): print(f"Austin PID: {process.pid}") print(f"Python PID: {child_process.pid}") print(f"Command Line: {command_line}") def on_sample_received(self, line): print(line) def on_terminate(self, data): print(data) try: austin = EchoThreadedAustin() austin.start(["-i", "10000", "python3", "myscript.py"]) austin.join() except KeyboardInterrupt: pass
-
get_thread
()¶ Get the underlying
threading.Thread
instance.As this leaks a bit of the implementation, interaction with the returned thread object should be done with care.
- Note
This is an extension of the base Austin abstract class.
- Return type
Optional
[Thread
]
-
join
(timeout=None)¶ Join the thread.
This is the same as calling
join()
on the underlying thread object.- Note
This is an extension of the base Austin abstract class.
- Return type
None
-
start
(args=None)¶ Start the Austin thread.
- Return type
None
-
This wrapper implements an thread-based API around Austin. This class offers
additional methods beside the base API of austin.BaseAustin
that allow
you to perform operations that are typical of thread-based applications, like
joining a thread to ensure a proper termination of the application.
The example above shows how to implement the same echo example of the simple case using this wrapper.
.austinrc
¶
The .austinrc
run-control file located in the user’s home folder can be used
to configure the wrappers. The basic implementation of
austin.config.AustinConfiguration
supports the option binary to
specify the location of the Austin binary. This is the third lookup option when
trying to locate the Austin binary in order to start sampling, as discussed at
the top of this page.
-
class
austin.config.
AustinConfiguration
¶ Bases:
object
Austin configuration borg.
-
property
binary
¶ Get the Austin binary path.
- Return type
str
-
reload
()¶ Reload the configuration from the run-control file.
- Return type
None
-
save
()¶ Save the current configuration to file.
- Return type
None
-
property
Applications that need custom configuration can sub-class
austin.config.AustinConfiguration
and modify the internal state
self._data, which is then dumped to back to the .austinrc file via a call to
save. The file format is TOML.