Package: tiny-storage
SummaryLibrary for application data storage. It is:tinykey-valuesingle-fileYAML basedExamplefromtiny_storageimportUnit,Typeimportsys# matches the file /etc/example-app/yaml or %PROGRAMDATA%\example-app\config.yamlconfig=Unit('example-app',Type.global_config)ifsys.argv[1]=='set-greeting':# changes greeting only if does not existifnotconfig('lines.greeting').try_put(sys.argv[2]):print('Greeting already exists. It should not be changed.')else:# prints greeting if it exists or given stringprint(config('lines.greeting').pull('Hello, world!'))Installationpipinstalltiny_storageFull guide as a tiny_storage iceberg1. Hello worldSuppose you want to store a configuration of your application between sessions.fromtiny_storageimportUnit# create a storage unitconfig=Unit('application-name')# write the dataconfig('the-best-number-ever').push(42)The code above will create a YAML configuration file in the appropriate place and save the number 42 asthe-best-number-everentry.2. Accessing dataSyntax for accessing data is the following:config('<dot separated path in config>').<accessmethod>(<alternativevalue>)There are 5 access methods in total, but the get/set functionality is realized in pull/push methods.config('essential.greeting').pull('hello')# get a greeting from config or 'hello'config('essential.greeting').push('hi')# set a greeting as 'hi'3. Storing config in different placesYou can define what type of config do you need and tiny_storage will choose the place according to standard of your OS. For example, to store data in global configuration file you passType.global_configto your storage unit definition, and it will go to/etcin linux and to%PROGRAM_DATA%in windows.fromtiny_storageimportUnit,Typeconfig=Unit('application-name',Type.global_config)The list of all config types:Data typeWindowsLinuxType.local{name}.yaml{name}.yamlType.user%APPDATA%/{name}/{name}.yaml$HOME/.{name}.yamlType.user_config%APPDATA%/{name}/config.yaml$HOME/.config/{name}.yamlType.global_data%PROGRAMDATA%/{name}/data.yaml/var/lib/{name}.yamlType.global_config%PROGRAMDATA%/{name}/config.yaml/etc/{name}.yamlYou can also pass your own config type as a(str) -> Pathfunction that constructs a path to config from the name.config=Unit('application-name',lambdaname:Path(f"/root/.{name}.yaml"))4. Access methodsThere are 5 most common cases of configuration data access and they are encapsulated into 5 access methods..push(value)to forcefully set an entryprint(f'Greeting was updated to{config("greeting").push("hi")}').pull(value)to get an entry or default valueprint(f'Current greeting is{config("greeting").pull("<none>")}').put(value)to get the value or set it if it doesn't existprint(f'{config("greeting").put("Hello")}, world').try_push(value)to push and know whether something changesifnotconfig("greeting").try_push(input()):print("You input the same greeting. Why are you doing that?").try_put(value)to put and know whether something changesifconfig("greeting").try_put("Hello"):print("There was no greeting, so I put hello as one.")5. LazinessYou can also pass a callable with no arguments as a value and it will be interpreted as a lazy value and be called only if it was used. For example, this hello world program will ask for a greeting only on the first launch:print(config('greeting').put(input("greeting: ")),"world!")