-
Notifications
You must be signed in to change notification settings - Fork 1
Advanced Usage
The CLI interface of anonpy
creates a INI file on launch at the location of get_resource_path("anonpy")
:
[client]
download_directory = C:\Users\stefan.greve\downloads
token = None
user_agent = None
proxies = None
enable_logging = False
log_level = 20
verbose = True
force = False
[security]
hash = sha256
[server]
api = https://pixeldrain.com/api/
upload = /file
download = /file/{}
preview = /file/{}/info
Note that the $home
variable will be expanded in the configuration file itself by the time of writing. Use the ConfigHandler
class to programmatically interact with this configuration, or to create your own.
import json
from anonpy.internals import ConfigHandler, get_resource_path
folder = get_resource_path("my_module")
path = folder.joinpath("config.ini")
with ConfigHandler(path) as config_handler:
config_handler.add_section("test", settings={
"hello": "world",
"number": 2,
"switch": True
})
# pretty-print output
print(json.dumps(config_handler.json, indent=2))
The context manager will save the content of the config_handler
object on exit to path
. This class can also be used without a context manager. Passing no path
to the constructor is also possible, but will raise an error when the save
method is invoked.
resource_folder = get_resource_path("anonpy")
# read existing configuration file
config = ConfigHandler(resource_folder / "anonpy.ini")
config.read()
# prints 'True' with default settings
print(config.get_optioen("client", "verbose"))
The AnonPy
class inherits from RequestHandler
for establishing communication through session objects. Since the registration process requires an preview
(aka info
) endpoint for the progress bars, you may want to use RequestHandler
as a base class and implement the methods for download
and upload
yourself.
The providers
namespace implements custom-tailored solutions to specific REST APIs and serve as a reference implementation for hooking up your backend of choice, but you can also implement your own classes by using inheritance:
from anonpy import AnonPy
from anonpy.internals import Authorization
from typing import Final, Self
class PixelDrain(AnonPy):
def __init__(self: Self, token: Optional[str]=None) -> None:
self.api: Final = "https://pixeldrain.com/api/"
self.endpoint = Endpoint(upload="/file", download="file/{}", preview="/file/{}/info")
# there are more optional parameters to configure the bahvior of the base class
super().__init__(api=self.api, endpoint=self.endpoint)
# configure basic authorization
if token: self.set_credentials(Authorization.Basic)
The code above is used to showcase the mechanics of inheriting from
AnonPy
, thePixelDrain
class can be imported from theanonpy.providers
namespace directly
Alternatively, you can also use the Endpoint
data class directly:
from anonpy import AnonPy, Endpoint
api = "https://pixeldrain.com/api/"
# preview/info endpoint is required for the progress bar to estimate the time for completion
endpoint = Endpoint(upload="/file", download="file/{}", preview="/file/{}/info")
# declare a new pseudo type for your backend (optional)
type PixelDrain = AnonPy
# register the provider to AnonPy
pixel = PixelDrain(api, endpoint)
The internals
namespace supplies the facilities that are necessary for structured logging and currently supports the following targets:
-
None
(print logs to terminal) *.csv
*.json
*.log | *.txt | *.dat
The LogHandler
class implements a wrapper around Python's built-in logging
module. The LogLevel
Enum mirrors the native log levels, to further reinforce this point.
from anonpy.internals import LogHandler, LogLevel
from pathlib import Path
target = "test_anonpy.csv"
# create a new logger object
logger = LogHandler(level=LogLevel.DEBUG)
# use the builder pattern for setting up targets
logger \
.set_base_path(path=Path.home()) \
.add_handler(target) \
.add_handler(None)
logger.debug("Hello, %s", "World")
# read the entire log history into memory
log_book = logger.get_log_history(target)
print(log_book)
# call on application exit
logger.shutdown()
Note that the built-in
logging
library is optimized to use the%s
formatting style. Using string interpolation ("f-strings") here might have an extract cost because the formatting would apply even if the message is not logged.
The AnonPy
or PixelDrain
contructors take a enable_logging
parameter (disabled by default) for toggling the logging behavior. The default implementation of download
, preview
and upload
will log their calls if enable_logging
is set to True
, but will raise a TypeError
exception if no handler was attached prior to these function invocations.
from anonpy.providers import PixelDrain
pixel = PixelDrain(enable_logging=True)
# log to console
pixel.logger.add_handler("console")
upload = pixel.preview("Aozkv26f", progressbar=True)
It's also possible to use the log handler from the
rich
library by passingrich_console
instead ofconsole
to theadd_handler
method
TODO