Welcome to Woger’s documentation!

Woger home

Woger — Python library for workspace management

Why Woger?

Woger allows you to

  • easily create directory structure
  • manage multiple versions of your directories
  • track the state of each workspace
  • transition from one version to another

Installation

pip3 install woger

Examples

Path

Basic path structure
>>> from woger import Workspace, BasePathStructure
>>>
>>> class PathStructure(BasePathStructure):
...     images = 'img'
...     json = 'json'
...     xml = 'xml'
>>>
>>> path = Workspace.construct('root', PathStructure).path
>>> print(path.images)
root/img
Path loader binding
>>> from woger import BasePathStructure, Bind, Workspace
>>> import tempfile
>>>
>>> content = 'Example of binding'
>>>
>>> def create_example_txt(path, ws_root, action):
...     ws = Workspace.construct(ws_root)
...     with ws.track(action):
...         print('Creating example.txt...')
...         with open(str(path), 'w') as f:
...             f.write(content)
...     return True
...
>>>
>>> class PathStructure(BasePathStructure):
...     example = Bind('example.txt', create_example_txt)
...
>>>
>>> with tempfile.TemporaryDirectory() as root:
...     ps = Workspace.construct(root, PathStructure).path
...
...     with open(str(ps.example), 'r') as f:
...         print(f.read())
...
Creating example.txt...
Example of binding
Composition of path structures
>>> from woger import BasePathStructure
>>>
>>> class PS1(BasePathStructure):
...     xml = 'xml'
>>>
>>> class PS2(BasePathStructure):
...     json = 'json'
>>>
>>> class PathStructure(PS1, PS2):
...     txt = 'txt'
>>>
>>> ps = PathStructure('root')
>>> print(ps.txt, ps.json, ps.xml, sep='\n')
root/txt
root/json
root/xml

Data

Basic data loader
>>> from woger import Workspace, BasePathStructure, BaseData
>>>
>>> def load_json(ws):
...     return '{}'
>>>
>>> class Data(BaseData):
...     json = load_json
>>>
>>> data = Data()
>>> print(data.json)
{}
Pass data loader args
>>> import json
>>> from woger import Workspace, BasePathStructure, BaseData
>>>
>>> def load_json(data):
...     return json.dumps(data.passed_arg)
>>>
>>> class Data(BaseData):
...     passed_arg = lambda data: dict(value=[4, 2])
...     json = load_json
>>>
>>> data = Data()
>>> print(data.json)
{"value": [4, 2]}
Chained data loaders
>>> from woger import BaseData
>>>
>>> def load_json(data):
...     return '{}'
>>>
>>> def convert_to_xml(data):
...     return (
...         data.json
...         .replace('{', '<data>')
...         .replace('}', '</data>')
...     )
>>>
>>> class Data(BaseData):
...     json = load_json
...     xml = convert_to_xml
>>>
>>> data = Data()
>>> print(data.xml)
<data></data>
Composition of data
>>> from woger import BaseData
>>>
>>> class A(BaseData):
...     xml = lambda data: 'xml'
>>>
>>> class B(BaseData):
...     json = lambda data: 'convert {} to json'.format(data.xml)
>>>
>>> class C(A, B):
...     all = lambda data: (data.xml, data.json)
>>>
>>> data = C()
>>> print(data.xml, data.json, data.all, sep='\n')
xml
convert xml to json
('xml', 'convert xml to json')

Storage

Basic storage
>>> from woger import WorkspaceStorage, BasePathStructure, Workspace
>>>
>>> storage = WorkspaceStorage()
>>>
>>> print(len(storage))
0
>>>
>>> ws = Workspace.construct('257', BasePathStructure)
>>> storage.add(ws)
>>>
>>> print(len(storage))
1
>>> ws = Workspace.construct('175', BasePathStructure)
>>> storage.add(ws)
>>>
>>> print(len(storage))
2
>>> print(storage)
<WorkspaceStorage [175, 257]>

Workspace

Basic workspace
>>> from woger import Workspace, BasePathStructure, BaseData
>>>
>>> class PathStructure(BasePathStructure):
...     json = 'json'
...     xml = 'xml'
>>>
>>> def load_json(ws: Workspace):
...     return '{}'
>>>
>>> class Data(BaseData):
...     json = load_json
>>>
>>> ws = Workspace.construct('root', PathStructure, Data)
>>> print(ws.data.json)
{}
Workspace with chained loaders
>>> from woger import Workspace, BasePathStructure, BaseData
>>>
>>> class PathStructure(BasePathStructure):
...     json = 'json'
...     xml = 'xml'
>>>
>>> def load_json(data):
...     return '{}'
>>>
>>> def convert_to_xml(data):
...     return (
...         data.json
...         .replace('{', '<data>')
...         .replace('}', '</data>')
...     )
>>>
>>> class Data(BaseData):
...     json = load_json
...     xml = convert_to_xml
>>>
>>> ws = Workspace.construct('root', PathStructure, Data)
>>> print(ws.data.xml)
<data></data>

Workspace manager

Workspace management
>>> from woger import WorkspaceManager, BasePathStructure
>>> import tempfile
>>>
>>> class PathStructure(BasePathStructure):
...     loaded = 'loaded.xml'
...     parsed = 'parsed.json'
>>>
>>> manager = WorkspaceManager('store', PathStructure)
>>>
>>> manager.create(1346)
<Workspace(store/1346)>
>>>
>>> manager.create(542)
<Workspace(store/542)>
>>>
>>> manager.target_latest()
>>> manager.target()
<Workspace(store/1346)>
>>>
>>> manager.current() is None
True
>>>
>>> manager.update()
>>> manager.current() is manager.target()
True
Manager with data bindings
>>> from woger import WorkspaceManager, BasePathStructure, BaseData
>>> from collections import OrderedDict
>>>
>>> class PathStructure(BasePathStructure):
...     loaded = 'loaded.txt'
...     parsed = 'parsed.json'
>>>
>>> def load_txt(data):
...     return '\n'.join([
...         'This text-mapping of values',
...         'Goal-convert to json dict',
...     ])
>>>
>>> def parse_loaded(data):
...     content = data.loaded
...     return OrderedDict(
...         line.split('-')
...         for line
...         in content.split('\n')
...     )
>>>
>>> class Data(BaseData):
...     loaded = load_txt
...     parsed = parse_loaded
>>>
>>> manager = WorkspaceManager('storage', PathStructure, Data)
>>>
>>> ws = manager.create(1346)
>>> print(ws)
<Workspace(storage/1346)>
>>>
>>> print(manager)
<WorkspaceManager(root=storage, storage=<WorkspaceStorage [1346]>)>
>>>
>>> ws.data.parsed
OrderedDict([('This text', 'mapping of values'), ('Goal', 'convert to json dict')])

License

MIT

API

woger.ActionStatus List of action statuses
woger.ActionTracker(action: str, state_path: str) Manages and monitors actions
woger.WorkspaceManager(root[, …]) Manages workspaces
woger.WorkspaceState(path: str) Manages workspace state
woger.WorkspaceStorage(…) Stores workspaces
woger.Workspace(data) Wrapper interface to store path and data
woger.BasePathStructure(root: str, *[, data]) Base class for the path structure
woger.BaseData([path_structure]) Base class for the data

woger package

Submodules

woger.action_status module

class woger.action_status.ActionStatus[source]

Bases: enum.Enum

List of action statuses

failed = 'failed'
finished = 'finished'
started = 'started'
undefined = None

woger.action_tracker module

class woger.action_tracker.ActionTracker(action: str, state_path: str, path=None)[source]

Bases: object

Manages and monitors actions

failed()[source]

Returns True if the action has failed

finished()[source]

Returns True if the action has finished

started()[source]

Returns True if the action has started and is pending

state

WorkspaceState object linked to self.state_path

status()[source]

Returns a string representation of the current action status

undefined()[source]

Returns True if the action state is not defined

woger.base_data module

class woger.base_data.BaseData(path_structure=None)[source]

Bases: object

Base class for the data

Examples

Basic data loader

Pass data loader args

Chained data loaders

woger.base_path_structure module

class woger.base_path_structure.BasePathStructure(root: str, *, data=None)[source]

Bases: object

Base class for the path structure

track(action: str) → woger.action_tracker.ActionTracker[source]

Creates an ActionTracker object and targets action action

It’s a shortcut which creates an ActionTracker for you

..code-block:: python

>>> from woger import BasePathStructure
>>>
>>> class PathStructure(BasePathStructure):
...     json = 'json'
>>>
>>> ps = PathStructure('root')
>>>
>>> # WRONG
>>> tracker = ActionTracker('load_json', 'root/state.json', ps.json)
>>>
>>> # RIGHT
>>> tracker = ps.track(ps.json.action())
Parameters:action (str) – Action to track
Returns:
Return type:ActionTracker instance

woger.bind module

class woger.bind.Bind(path: str, loader=None)[source]

Bases: str

String wrapper class to hold a loader attribute

path

str

loader

function

action()[source]

Construct an action name from a Bind object

classmethod from_action(action)[source]

Construct a Bind object from an action name

woger.constants module

woger.data_meta module

class woger.data_meta.DataMeta[source]

Bases: type

Meta class for BaseData subclasses

woger.loaders module

woger.loaders.create_dir(path)[source]
woger.loaders.create_file(path)[source]
woger.loaders.default_loader(path: str, root: str, action: str)[source]
woger.loaders.is_dir(path)[source]

woger.manager module

class woger.manager.WorkspaceManager(root, path_structure_cls=None, data_cls=None, workspace_cls=None)[source]

Bases: object

Manages workspaces

Allows you to - create workspaces - load workspaces from directory - manage current, target and latest workspaces - search for workspaces with finished actions

Examples

Workspace management

Manager with data bindings

create(ws_id) → woger.workspace.Workspace[source]

Creates a Workspace

Parameters:ws_id (str or int) – Workspace id
current() → typing.Union[woger.workspace.Workspace, NoneType][source]

Returns current workspace

current_ws_id

Returns current workspace id

find_latest_finished(action) → typing.Union[woger.workspace.Workspace, NoneType][source]

Searches for latest workspace with finished action action

latest() → woger.workspace.Workspace[source]

Returns latest workspace

target() → woger.workspace.Workspace[source]

Returns target workspace

target_latest()[source]

Sets the target id equal to the latest id

target_ws_id

Returns target workspace id

update()[source]

Migrates from current workspace to target one

Sets the current workspace id equal to the target workspace id

woger.path_structure_meta module

class woger.path_structure_meta.CustomProperty(p, action)[source]

Bases: property

class woger.path_structure_meta.PathStructureMeta[source]

Bases: type

woger.state module

class woger.state.WorkspaceState(path: str)[source]

Bases: object

Manages workspace state

State is written to file each time anything changes

path

str – Path of the file to store the state in

woger.storage module

class woger.storage.WorkspaceStorage(workspaces: typing.Union[typing.Iterable[woger.workspace.Workspace], NoneType] = None, limit: typing.Union[int, NoneType] = None)[source]

Bases: object

Stores workspaces

add(workspace: woger.workspace.Workspace)[source]

Add a workspace

Parameters:workspace (Workspace) – Workspace to be added
at(index) → typing.Union[woger.workspace.Workspace, NoneType][source]

Gets workspace from storage by index

To get the oldest workspace use index 0 To get the latest workspace use index -1

items()[source]
keys()[source]
classmethod load_from_directory(root, *, path_structure_cls=None, data_cls=None, workspace_cls=None)[source]

Creates a workspaces instance and loads all the workspaces from the root path

root

str – Storage root path

path_structure_cls

BasePathStructure class object

data_cls

BaseData class object

workspace_cls

Workspace class object

values() → typing.List[woger.workspace.Workspace][source]

woger.workspace module

class woger.workspace.Workspace(data)[source]

Bases: object

Wrapper interface to store path and data

id

int or str

root

str

path

BasePathStructure

data

BaseData

Examples

Basic workspace

Workspace with chained loaders

classmethod construct(root, path_structure_cls=None, data_cls=None)[source]

Creates a Workspace object

Convinient alternative constructor

id

Workspace id

Id is used to sort workspaces from oldest to latest

path

Bound path structure object

root

Workspace root

track(action: str) → woger.action_tracker.ActionTracker[source]

Creates an ActionTracker object to manage action action

It’s a shortcut to avoid creating ActionTracker directly

action

str – Action to track

Module contents

class woger.Workspace(data)[source]

Bases: object

Wrapper interface to store path and data

id

int or str

root

str

path

BasePathStructure

data

BaseData

Examples

Basic workspace

Workspace with chained loaders

classmethod construct(root, path_structure_cls=None, data_cls=None)[source]

Creates a Workspace object

Convinient alternative constructor

id

Workspace id

Id is used to sort workspaces from oldest to latest

path

Bound path structure object

root

Workspace root

track(action: str) → woger.action_tracker.ActionTracker[source]

Creates an ActionTracker object to manage action action

It’s a shortcut to avoid creating ActionTracker directly

action

str – Action to track

class woger.WorkspaceState(path: str)[source]

Bases: object

Manages workspace state

State is written to file each time anything changes

path

str – Path of the file to store the state in

class woger.WorkspaceStorage(workspaces: typing.Union[typing.Iterable[woger.workspace.Workspace], NoneType] = None, limit: typing.Union[int, NoneType] = None)[source]

Bases: object

Stores workspaces

add(workspace: woger.workspace.Workspace)[source]

Add a workspace

Parameters:workspace (Workspace) – Workspace to be added
at(index) → typing.Union[woger.workspace.Workspace, NoneType][source]

Gets workspace from storage by index

To get the oldest workspace use index 0 To get the latest workspace use index -1

items()[source]
keys()[source]
classmethod load_from_directory(root, *, path_structure_cls=None, data_cls=None, workspace_cls=None)[source]

Creates a workspaces instance and loads all the workspaces from the root path

root

str – Storage root path

path_structure_cls

BasePathStructure class object

data_cls

BaseData class object

workspace_cls

Workspace class object

values() → typing.List[woger.workspace.Workspace][source]
class woger.WorkspaceManager(root, path_structure_cls=None, data_cls=None, workspace_cls=None)[source]

Bases: object

Manages workspaces

Allows you to - create workspaces - load workspaces from directory - manage current, target and latest workspaces - search for workspaces with finished actions

Examples

Workspace management

Manager with data bindings

create(ws_id) → woger.workspace.Workspace[source]

Creates a Workspace

Parameters:ws_id (str or int) – Workspace id
current() → typing.Union[woger.workspace.Workspace, NoneType][source]

Returns current workspace

current_ws_id

Returns current workspace id

find_latest_finished(action) → typing.Union[woger.workspace.Workspace, NoneType][source]

Searches for latest workspace with finished action action

latest() → woger.workspace.Workspace[source]

Returns latest workspace

target() → woger.workspace.Workspace[source]

Returns target workspace

target_latest()[source]

Sets the target id equal to the latest id

target_ws_id

Returns target workspace id

update()[source]

Migrates from current workspace to target one

Sets the current workspace id equal to the target workspace id

class woger.ActionTracker(action: str, state_path: str, path=None)[source]

Bases: object

Manages and monitors actions

failed()[source]

Returns True if the action has failed

finished()[source]

Returns True if the action has finished

started()[source]

Returns True if the action has started and is pending

state

WorkspaceState object linked to self.state_path

status()[source]

Returns a string representation of the current action status

undefined()[source]

Returns True if the action state is not defined

class woger.ActionStatus[source]

Bases: enum.Enum

List of action statuses

failed = 'failed'
finished = 'finished'
started = 'started'
undefined = None
class woger.BasePathStructure(root: str, *, data=None)[source]

Bases: object

Base class for the path structure

track(action: str) → woger.action_tracker.ActionTracker[source]

Creates an ActionTracker object and targets action action

It’s a shortcut which creates an ActionTracker for you

..code-block:: python

>>> from woger import BasePathStructure
>>>
>>> class PathStructure(BasePathStructure):
...     json = 'json'
>>>
>>> ps = PathStructure('root')
>>>
>>> # WRONG
>>> tracker = ActionTracker('load_json', 'root/state.json', ps.json)
>>>
>>> # RIGHT
>>> tracker = ps.track(ps.json.action())
Parameters:action (str) – Action to track
Returns:
Return type:ActionTracker instance
class woger.BaseData(path_structure=None)[source]

Bases: object

Base class for the data

Examples

Basic data loader

Pass data loader args

Chained data loaders

class woger.Bind(path: str, loader=None)[source]

Bases: str

String wrapper class to hold a loader attribute

path

str

loader

function

action()[source]

Construct an action name from a Bind object

classmethod from_action(action)[source]

Construct a Bind object from an action name