theoretical pyhton stubs and bindings

but they are not usable for some reason
This commit is contained in:
Christoph J. Scherr 2023-07-09 19:08:55 +02:00
parent 9fb82b5caa
commit 0f2b62c999
Signed by: PlexSheep
GPG Key ID: 25B4ACF7D88186CC
11 changed files with 273 additions and 22 deletions

View File

@ -4,6 +4,8 @@
`libpt` is originally implemented in rust, but offers a python module too.
"""
from . import logger
from . import networking
from . import common
def is_loaded() -> bool:
"""

View File

@ -0,0 +1,7 @@
"""
common functionalities
This module implements common functionality useful for many use cases, such as macros,
Formatting functions and more.
"""
from . import printing

View File

@ -0,0 +1,14 @@
"""
tools that make printing stuff better
"""
def divider() -> str:
"""
Quickly get a one line visual divider
"""
...
def print_divider():
"""
Quickly print a one line visual divider
"""
...

View File

@ -0,0 +1,7 @@
"""
# various networking tools
The networking module contains various tools related to connections. For example, it contains a
tool that has the purpose to check if your connection is consistently available.
"""
from . import monitoring

View File

@ -0,0 +1,7 @@
"""
# monitor your network
This module offers functions to monitor your network.
"""
from . import uptime

View File

@ -0,0 +1,84 @@
"""
# monitor your network uptime
This method offers a way to monitor your networks/hosts uptime. This is achieved by making
HTTPS requests to a given list of
"""
class UptimeStatus:
"""
Describes an uptime status
UptimeStatus describes the result of an uptime check.
"""
""" true if the [`UptimeStatus`] is considered successful"""
success: bool
""" the percentage of reachable urls out of the total urls"""
success_ratio: int
""" the percentage of reachable urls out of the total urls that need to be reachable in order
for this [`UptimeStatus`] to be considered a success.
"""
success_ratio_target: int
""" the number of reachable [`urls`](UptimeStatus::urls) """
reachable: int
"""URL list cant be ported to python, use UptimeStatus.urls()"""
__urls: ...
def __init__(self, success_ratio_target: int, url_strs: list[str]) -> None:
"""
create a new UptimeStatus and check it
`success_ratio_target` should never be more than 100 (it represents a success percentage)
"""
...
def check(self) -> None:
"""
checks if the stored urls
Makes the actual https requests and updates fields accordingly.
This method can block some time, as the web requests are implemented as blocking and
executed by the shared library (not in python)
"""
...
def calc_success(self) -> None:
"""
calculate the success based on the `reachable` and `total`
Calculates the ratio of [reachable]/
(length of [__urls]).
Calculates a [`success_ratio`] from that, by multiplying with 100, then flooring.
If the [`success_ratio`] is greater than or equal to the [`success_ratio_target`],
the [`UptimeStatus`] will be considered a success.
In the special case that no URLs to check for have been provided, the check will be
considered a success, but the [`success_ratio`] will be `0`.
Note: does not check for networking, use [`check()`] for that.
"""
...
def urls(self) -> list[str]:
"""
get urls for python
Since [`__urls`] has no python equivalent, return the urls as a `list[str]` in
Python.
"""
...
def continuous_uptime_monitor(success_ratio_target: int, urls: list[str], interval: int) -> None:
"""
Uptime monitor
This function continuously monitors the uptime of your host/network.
On change of status, an update will be logged at INFO Level, containing
information on your current status, including timestamps of the last up/down time and durations
since.
"""
...

View File

@ -37,6 +37,9 @@ static LONG_ABOUT_ROOT: &'static str = r##"
//// STATICS ///////////////////////////////////////////////////////////////////////////////////////
/// ## Main struct for parsing CLI arguments
///
/// This struct describes the complete commandline options/arguments that [pt](crate) can take. It
/// makes use of composition to build a complex system of commands, subcommands, flags and options.
#[derive(Debug, Clone, Parser)]
#[command(
author,
@ -49,12 +52,13 @@ r#"libpt: {version}{about-section}Author:
{usage-heading} {usage}{all-args}{tab}"#
)]
pub struct Cli {
// clap_verbosity_flag seems to make this a global option implicitly
/// set a verbosity, multiple allowed (f.e. -vvv)
#[command(flatten)]
pub verbose: Verbosity<InfoLevel>,
/// show logger meta
#[arg(short, long)]
#[arg(short, long, global = true)]
pub log_meta: bool,
/// choose a subcommand
@ -63,19 +67,20 @@ pub struct Cli {
}
//// ENUMS /////////////////////////////////////////////////////////////////////////////////////////
/// # defines the top level commands
/// ## defines the top level commands
#[derive(Debug, Clone, Subcommand)]
#[non_exhaustive]
pub enum Commands {
/// networking commands
Net {
/// Networking subcommands
#[command(subcommand)]
command: NetCommands,
},
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// defines the networking commands
/// ## defines the networking commands
#[derive(Debug, Clone, Subcommand)]
#[non_exhaustive]
pub enum NetCommands {

View File

@ -1,6 +1,8 @@
//! # Main executable of pt
//!
//! This module contains all code specific to the executable version of [`libpt`]: `pt`.
//! This module contains all code specific to the executable version of [`libpt`]: [`pt`](crate).
//!
//!
//// ATTRIBUTES ////////////////////////////////////////////////////////////////////////////////////
// we want docs
@ -22,7 +24,7 @@ use env_logger;
use clap::Parser;
mod args;
pub mod args;
use args::*;
//// CONSTANTS /////////////////////////////////////////////////////////////////////////////////////
@ -38,10 +40,8 @@ use args::*;
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
//// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
/// ## Main function of the `pt` binary
fn main() {
/// ## Main function of the [`pt`](crate) binary
pub fn main() {
let cli = Cli::parse();
if cli.log_meta {
// set up our logger to use the given verbosity
@ -68,8 +68,8 @@ fn main() {
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Process `Net` subcommands
fn net(cli: &Cli, command: NetCommands) {
/// ## Process [`Net`](args::NetCommands) subcommands
pub fn net(cli: &Cli, command: NetCommands) {
match command {
NetCommands::Monitor {
repeat,
@ -97,6 +97,8 @@ fn net(cli: &Cli, command: NetCommands) {
println!("{}", status);
}
}
NetCommands::Discover {} => {}
NetCommands::Discover {} => {todo!()}
}
}
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////

View File

@ -12,7 +12,9 @@
//// IMPORTS ///////////////////////////////////////////////////////////////////////////////////////
// reimport our macros to this module, so the user does not get confused when importing the macros
pub use crate::divider;
pub use crate::println_divider;
pub use crate::print_divider;
use pyo3::prelude::*;
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
@ -32,7 +34,7 @@ macro_rules! divider {
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Quickly print a one line visual divider
#[macro_export]
macro_rules! println_divider {
macro_rules! print_divider {
() => {{
println!("{}", divider!())
}};
@ -45,5 +47,17 @@ macro_rules! println_divider {
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
//// PUBLIC FUNCTIONS //////////////////////////////////////////////////////////////////////////////
/// python interface for [`divider`], can also be used with rust
#[pyfunction]
pub fn divider() -> String {
divider!()
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// python interface for [`print_divider`], can also be used with rust
#[pyfunction]
pub fn print_divider() {
print_divider!()
}
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////

View File

@ -1,4 +1,4 @@
//! # root module of `libpt`
//! # `libpt`
//!
//! [`libpt`](crate) contains my personal code. It is compiled as all of the following:
//!
@ -42,11 +42,71 @@ pub fn is_loaded() -> bool {
//// PRIVATE FUNCTIONS /////////////////////////////////////////////////////////////////////////////
/// ## Python module: logger
#[pymodule]
fn py_logger(py: Python, m: &PyModule) -> PyResult<()> {
let logger_module = PyModule::new(py, "logger")?;
logger_module.add_class::<Logger>()?;
fn py_logger(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "logger")?;
module.add_class::<Logger>()?;
m.add_submodule(logger_module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: common
#[pymodule]
fn py_common(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "common")?;
py_common_printing(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: common.printing
#[pymodule]
fn py_common_printing(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "printing")?;
module.add_function(wrap_pyfunction!(common::printing::divider, module)?)?;
module.add_function(wrap_pyfunction!(common::printing::print_divider, module)?)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking
#[pymodule]
fn py_networking(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "networking")?;
py_networking_monitoring(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking.monitoring
#[pymodule]
fn py_networking_monitoring(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "monitoring")?;
py_networking_monitoring_uptime(py, module)?;
parent.add_submodule(module)?;
Ok(())
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// ## Python module: networking.monitoring.uptime
#[pymodule]
fn py_networking_monitoring_uptime(py: Python, parent: &PyModule) -> PyResult<()> {
let module = PyModule::new(py, "uptime")?;
module.add_class::<networking::monitoring::uptime::UptimeStatus>()?;
module.add_function(wrap_pyfunction!(
networking::monitoring::uptime::continuous_uptime_monitor,
module
)?)?;
parent.add_submodule(module)?;
Ok(())
}
@ -58,7 +118,9 @@ fn py_logger(py: Python, m: &PyModule) -> PyResult<()> {
fn _libpt(py: Python, m: &PyModule) -> PyResult<()> {
m.add_function(wrap_pyfunction!(is_loaded, m)?)?;
// load logger module
// load sub modules
py_common(py, m)?;
py_logger(py, m)?;
py_networking(py, m)?;
Ok(())
}

View File

@ -2,6 +2,8 @@
//!
//! This method offers a way to monitor your networks/hosts uptime. This is achieved by making
//! HTTPS requests to a given list of
//!
//! Warning: This module is not unit tested.
//// ATTRIBUTES ////////////////////////////////////////////////////////////////////////////////////
// we want docs
@ -26,6 +28,8 @@ use reqwest::{self, Url};
use humantime::{format_duration, format_rfc3339};
use std::time::SystemTime;
use pyo3::prelude::*;
use crate::divider;
//// TYPES /////////////////////////////////////////////////////////////////////////////////////////
@ -45,6 +49,7 @@ pub const DEFAULT_CHECK_URLS: &'static [&'static str] =
/// ## Describes an uptime status
///
/// [`UptimeStatus`] describes the result of an uptime check.
#[pyclass]
pub struct UptimeStatus {
/// true if the [`UptimeStatus`] is considered successful
pub success: bool,
@ -60,9 +65,11 @@ pub struct UptimeStatus {
}
//// IMPLEMENTATION ////////////////////////////////////////////////////////////////////////////////
/// Main implementation
impl UptimeStatus {
/// ## create a new `UptimeStatus` and perform it's check
pub fn new(success_ratio_target: u8, urls_str: &Vec<String>) -> Self {
pub fn new(success_ratio_target: u8, url_strs: &Vec<String>) -> Self {
assert!(success_ratio_target <= 100);
let mut status = UptimeStatus {
success: false,
success_ratio: 0,
@ -70,7 +77,7 @@ impl UptimeStatus {
reachable: 0,
urls: Vec::new(),
};
for s in urls_str {
for s in url_strs {
let url = reqwest::Url::from_str(&s);
if url.is_ok() {
status.urls.push(url.unwrap());
@ -136,6 +143,45 @@ impl UptimeStatus {
trace!("calculated success as: {}", self.success)
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Implementation of the Python interface
#[pymethods]
impl UptimeStatus {
/// calls [`new()`](UptimeStatus::new) with python compatible arguments
#[new]
pub fn py_new(success_ratio_target: u8, url_strs: Vec<String>) -> Self {
Self::new(success_ratio_target, &url_strs)
}
/// Same as [`check()`](UptimeStatus::check)
#[pyo3(name = "check")]
pub fn py_check(&mut self) {
self.check();
}
/// Same as [`calc_success()`](UptimeStatus::calc_success)
#[pyo3(name = "calc_success")]
pub fn py_calc_success(&mut self) {
self.calc_success();
}
/// ## get urls for python
///
/// Since [`UptimeStatus::urls`] has no python equivalent, return the urls as a `list[str]` in
/// Python.
///
/// Practically, this is also handy for rust implementations that want to access the URLs as
/// [Strings](String).
pub fn urls(&self) -> Vec<String> {
let mut url_strs: Vec<String> = Vec::new();
for url in self.urls.clone() {
url_strs.push(url.to_string());
}
return url_strs;
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
impl fmt::Debug for UptimeStatus {
@ -181,6 +227,7 @@ impl fmt::Display for UptimeStatus {
/// On change of status, an update will be logged at [INFO Level](log::Level::Info), containing
/// information on your current status, including timestamps of the last up/down time and durations
/// since.
#[pyfunction]
pub fn continuous_uptime_monitor(success_ratio_target: u8, urls: Vec<String>, interval: u64) {
if urls.len() == 0 {
error!("No URLs provided. There is nothing to monitor.");