A modern simfile parsing & editing library for Python 3

Overview

simfile - for Python 3

A modern simfile parsing & editing library for Python 3.

Full documentation can be found on Read the Docs.

Features

Installation

simfile is available on PyPI:

pip3 install simfile

Quickstart

Load simfiles from disk using simfile.open or simfile.load:

>>> import simfile
>>> springtime = simfile.open('testdata/Springtime.ssc')
>>> springtime
<SSCSimfile: Springtime>
>>> with open('testdata/Kryptix.sm', 'r') as infile:
...     kryptix = simfile.load(infile)
...
>>> kryptix
<SMSimfile: Kryptix>

Use lowercase attributes to access most common properties:

>>> springtime.artist
'Kommisar'
>>> springtime.banner
'springbn.png'
>>> springtime.subtitle = '(edited)'
>>> springtime
<SSCSimfile: Springtime (edited)>

Alternatively, use uppercase strings to access the underlying dictionary:

>>> springtime['ARTIST']
'Kommisar'
>>> springtime['ARTIST'] is springtime.artist
True
>>> list(springtime.keys())[:7]
['VERSION', 'TITLE', 'SUBTITLE', 'ARTIST', 'TITLETRANSLIT', 'SUBTITLETRANSLIT', 'ARTISTTRANSLIT']

Charts are stored in a list under the .charts attribute and function similarly to simfile objects:

>>> len(springtime.charts)
9
>>> chart = springtime.charts[0]
>>> chart
<SSCChart: dance-single Challenge 12>
>>> list(chart.keys())[:7]
['CHARTNAME', 'STEPSTYPE', 'DESCRIPTION', 'CHARTSTYLE', 'DIFFICULTY', 'METER', 'RADARVALUES']

Developing

simfile uses Pipenv for dependency management. Activate the environment:

pipenv shell

To run the unit tests:

py -m unittest

To build the documentation:

docs/make html
Comments
  • Opening a simfile fails with latest msdparser (2.0.0b3)

    Opening a simfile fails with latest msdparser (2.0.0b3)

    Downgrading to msdparser==2.0.0b1 seems to resolve the issue for me.

    Python 3.9.1 (tags/v3.9.1:1e5d33e, Dec  7 2020, 17:08:21) [MSC v.1927 64 bit (AMD64)] on win32
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import simfile
    >>> simfile.open("Xuxa.sm")
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Users\w\AppData\Local\Programs\Python\Python39\lib\site-packages\simfile\__init__.py", line 89, in open
        return open_with_detected_encoding(
      File "C:\Users\w\AppData\Local\Programs\Python\Python39\lib\site-packages\simfile\__init__.py", line 137, in open_with_detected_encoding
        return (load(file, strict=strict), encoding)
      File "C:\Users\w\AppData\Local\Programs\Python\Python39\lib\site-packages\simfile\__init__.py", line 63, in load
        is_ssc = _detect_ssc(peek_file)
      File "C:\Users\w\AppData\Local\Programs\Python\Python39\lib\site-packages\simfile\__init__.py", line 46, in _detect_ssc
        for first_key, _ in parser:
      File "C:\Users\w\AppData\Local\Programs\Python\Python39\lib\site-packages\msdparser\__init__.py", line 202, in parse_msd
        for token, value in lex_msd(
      File "C:\Users\w\AppData\Local\Programs\Python\Python39\lib\site-packages\msdparser\__init__.py", line 366, in lex_msd
        chunk = textio.read(4096)
      File "C:\Users\w\AppData\Local\Programs\Python\Python39\lib\site-packages\simfile\_private\tee_file.py", line 13, in __getattr__
        return getattr(self._file, name)
    AttributeError: 'itertools._tee' object has no attribute 'read'
    
    opened by wermipls 3
  • MSD parser doesn't handle backslash escapes

    MSD parser doesn't handle backslash escapes

    First off, thanks for building this library! It's been remarkably easy to use for simfile introspection.

    I ran into this unfortunate edge case while parsing through DDR A20 PLUS content:

    Traceback (most recent call last):
      File "/Users/vyhd/.pyenv/versions/3.9.2/lib/python3.9/site-packages/simfile/__init__.py", line 89, in open
        return open_with_detected_encoding(
      File "/Users/vyhd/.pyenv/versions/3.9.2/lib/python3.9/site-packages/simfile/__init__.py", line 137, in open_with_detected_encoding
        return (load(file, strict=strict), encoding)
      File "/Users/vyhd/.pyenv/versions/3.9.2/lib/python3.9/site-packages/simfile/__init__.py", line 67, in load
        return SMSimfile(file=file, strict=strict)
      File "/Users/vyhd/.pyenv/versions/3.9.2/lib/python3.9/site-packages/simfile/base.py", line 139, in __init__
        self._parse(parse_msd(
      File "/Users/vyhd/.pyenv/versions/3.9.2/lib/python3.9/site-packages/simfile/sm.py", line 159, in _parse
        for (key, value) in parser:
      File "/Users/vyhd/.pyenv/versions/3.9.2/lib/python3.9/site-packages/msdparser/__init__.py", line 117, in parse_msd
        ps.write(char)
      File "/Users/vyhd/.pyenv/versions/3.9.2/lib/python3.9/site-packages/msdparser/__init__.py", line 62, in write
        raise MSDParserError(f"stray {repr(text)} encountered")
    msdparser.MSDParserError: stray 'G' encountered
    

    which was triggered by this line: #SOURCE:ゲーム「STEINS\;GATE」; in the SM file located at: https://zenius-i-vanisher.com/v5.2/viewsimfile.php?simfileid=45612

    It looks like StepMania's MSD parser allows you to use \ to escape any control character (source), so this lib probably should be able to as well.

    I... might be able to submit a PR for this sometime in the next few weeks? But I wanted to flag it now, in case someone gets to it first.

    bug 
    opened by vyhd 3
  • Simfile objects: find the default music, banner, background, etc. file paths if left blank

    Simfile objects: find the default music, banner, background, etc. file paths if left blank

    There are some idiosyncrasies in how simfiles are handled by StepMania that aren't modeled by this package at all currently. For example, if you want to load the banner for a simfile on disk, you can certainly try using os.path to Frankenstein the simfile's filename and sim.banner together... but that only works if the BANNER tag is filled in, which isn't guaranteed. (For example, quite a few files in UPSMH Online have a blank BANNER tag.) If you leave the field blank, StepMania will try to find the appropriate image file on its own! This also applies to the music path.

    While this logic can be implemented in client code, I think it warrants inclusion as part of this package, given that processing simfile data together with audio or image data is a pretty noteworthy use case. It also helps us work toward the goal of handling any simfile that StepMania accepts.

    I had an implementation section here previously, but I totally forgot that simfiles don't know their own filenames, so my proposed implementation was bogus. We would likely need a new submodule for loading a simfile's supplementary files.

    enhancement feedback wanted 
    opened by garcia 3
  • Should NOTES/NOTES2 be handled implicitly by SSCChart?

    Should NOTES/NOTES2 be handled implicitly by SSCChart?

    Keysounded SSC charts store their note data in a NOTES2 property instead of the usual NOTES (the two properties are mutually exclusive to my knowledge). This poses an interesting design problem for simfile: should invoking .notes / ['NOTES'] on an SSCChart use the NOTES2 data when present, or should this logic be kept in NoteData?

    Separation of concerns dictates that NoteData should decide where to find the note data, and SSCChart should stay free of "business logic" and act as a plain dictionary of properties. This is how the library works currently, but this functionality isn't particularly discoverable, and I can imagine a lot of users not understanding why they need to call notedata.update_chart(chart) instead of the more straightforward chart.notes = str(notedata). It would be nice if the straightforward solution just worked in all cases.

    Any ideas on how to resolve this elegantly?

    opened by garcia 2
  • Incorrect parsing for non-power-of-two notes

    Incorrect parsing for non-power-of-two notes

    Thanks for the great package!

    I noticed that when parsing charts with 12ths or 24ths, the underlying Fraction representation for Beats are very strange.

    Here's a minimal reproducing example where we parse an SM file with a single measure full of 12th notes and print the numerator and denominator of all Note objects:

    https://gist.github.com/jcjohnson/603d9b5ab50016429f762cf9a5db2af7

    When run, it gives the output:

    (0, 1)
    (6004799503160661, 18014398509481984)
    (6004799503160661, 9007199254740992)
    (1, 1)
    (6004799503160661, 4503599627370496)
    (7505999378950827, 4503599627370496)
    (2, 1)
    (5254199565265579, 2251799813685248)
    (6004799503160661, 2251799813685248)
    (3, 1)
    (7505999378950827, 2251799813685248)
    (8256599316845909, 2251799813685248)
    

    The problem is here: https://github.com/garcia/simfile/blob/master/simfile/notes/init.py#L169

    You are passing a float to the Fraction constructor rather than a pair of integers. This will behave fine when the fraction is a power of two (since these can be represented exactly as floating-point values) but will give strange behavior when the fraction is not a power of two.

    The fix is simple; you just need to use the Fraction constructor that accepts a pair of integers for the numerator and denominator. When run with --apply-patch=1, my test script above monkey-patches NoteData.__iter__ to apply this fix; this then gives a much more normal result when parsing the chart with 12th notes:

    (0, 1)
    (1, 3)
    (2, 3)
    (1, 1)
    (4, 3)
    (5, 3)
    (2, 1)
    (7, 3)
    (8, 3)
    (3, 1)
    (10, 3)
    (11, 3)
    
    opened by jcjohnson 2
  • Handle DISPLAYBPM edge cases

    Handle DISPLAYBPM edge cases

    The displaybpm function can't handle #DISPLAYBPM:; or malformed strings currently. I assume StepMania just ignores the field in these cases, but would be good to verify.

    opened by garcia 1
  • [2.1 beta] Asset discovery discrepancies

    [2.1 beta] Asset discovery discrepancies

    Found a couple of asset discovery discrepancies between simfile and StepMania:

    • bn.png is discovered by StepMania, but looking at the source code, I don't know why. It seems to look for a filename containing banner or ending with  bn (with a space!), neither of which seem to match bn.png. Maybe FindFirstFilenameContaining is doing something overly complex?
    • Matches need to be done case-insensitively (i.e. by converting the filenames being checked to lowercase). I think even assets that are explicitly specified need to be matched case-insensitively (e.g. #BACKGROUND:file.png; should resolve to a FILE.PNG) but it would be good to confirm this.
    bug 
    opened by garcia 1
  • simfile.convert: Stopgap for warp conversion

    simfile.convert: Stopgap for warp conversion

    We should add a stopgap for simfiles with warp events (WARPS tags for SSC, negative BPMs / stops for SM) so that we don't produce invalid simfiles. The lack of a stopgap necessitated a patch in ITL 2022. At minimum we should throw an exception in this scenario.

    bug 
    opened by garcia 1
  • Can't assign to `simfileobj.charts`

    Can't assign to `simfileobj.charts`

    >>> import simfile
    >>> simfileobj = simfile.open('testdata/Springtime.ssc')
    >>> simfileobj.charts = []
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: can't set attribute
    

    This really should work, but it doesn't currently. You can modify the charts list, but can't reassign it.

    bug 
    opened by garcia 1
  • Multi-value properties aren't handled correctly in SSC

    Multi-value properties aren't handled correctly in SSC

    Two bugs in simfile 2.0.0–2.1.0's SSC implementation break multi-value properties, causing them to be truncated or mangled past the first value:

    1. When opening an SSC file, the DISPLAYBPM and ATTACKS properties of both simfiles and charts stop parsing at the first :. For DISPLAYBPM, this means a BPM range of min:max will be incorrectly parsed as a static BPM of min. ATTACKS are completely broken as they use colon as a separator.
    2. The aforementioned properties are incorrectly serialized with colons escaped from SSCChart. This has the same effects described above, but this only affects values with colons that were written to the chart object manually (e.g. chart.displaybpm = "120:240") since the first bug shadows this bug during deserialization.
    opened by garcia 0
  • In difficulty sort example script, also apply changes to titletranslit

    In difficulty sort example script, also apply changes to titletranslit

    Stepmania sorts songs based off of their title transliteration if it exists (it looks like?), so songs with title transliterations aren't sorted by Stepmania in the way this script wants to achieve.

    This is my first code contribution to an open source repository, so I may have made some mistakes wrt style/correctness. Maybe a cleaner solution would be to make prefix_title_with_meter title/titletranslit independent and then call it twice? Curious to hear your thoughts :)

    opened by lucdar 0
  • Bump certifi from 2022.6.15 to 2022.12.7

    Bump certifi from 2022.6.15 to 2022.12.7

    Bumps certifi from 2022.6.15 to 2022.12.7.

    Commits

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    dependencies 
    opened by dependabot[bot] 0
  • docs:

    docs: "SM/SSC conversion"

    We should document simfile.convert with a little more grace than what the AutoAPI page currently has to offer.

    The dedicated page should include examples for practical use cases, like saving to both the SM and SSC file in a simfile directory, validating that the two files on disk have matching base properties, and backfilling missing SM files for the sake of StepMania builds that don't support SSC (like NotITG).

    docs 
    opened by garcia 0
  • simfile.timing.engine: Incorporate FAKES tag into

    simfile.timing.engine: Incorporate FAKES tag into "hittable" logic

    The SSC format includes a FAKES property (at both the simfile and chart level) that defines fake regions - beat ranges in which notes of all types are unhittable. This, together with warp segments, are the two reasons why a note might not be hittable, as observed in TimingData.h. (StepMania uses the term judgable here, but hittable appears to be used synonymously elsewhere in source code.)

    Right now, TimingEngine only marks warp regions as unhittable. Fixing this cleanly will probably require adding a fakes attribute to TimingData. Currently, the attributes in TimingData are scoped to just those required for TimingEngine to do its job, under which rule this addition makes perfect sense. However, it does count as an expansion to the public API, which will incur a minor version bump.

    Also of note: in the future, we may want to add all of the timing properties for which any chart-level data replaces the simfile-level data. This set of properties is documented in NotesLoaderSSC.cpp.

    enhancement 
    opened by garcia 0
  • simfile.timing.engine: convert negative BPMs to warps internally

    simfile.timing.engine: convert negative BPMs to warps internally

    Related to #5. The timing engine should handle negative BPMs as if they were warps. The best way to do this is almost certainly to convert them to warps internally, rather than trying to design the engine's internal data structures around this archaic hack.

    Right now TimingEngine is almost certainly prone to raising exceptions if given negative BPMs (I haven't tested it yet). At minimum, it won't correctly flag negative BPM warp regions as being un-hittable(). As such, this qualifies as a bug, although fixing it will likely constitute a feature release (and thus minor version bump) for #5.

    bug 
    opened by garcia 0
  • simfile.convert: warps to negative BPMs and vice-versa

    simfile.convert: warps to negative BPMs and vice-versa

    StepMania 3.9 infamously "supported" warp segments through a timing data exploit: setting the BPM to negative at some beat, then back to positive at a later beat, would warp the notes from the negative BPM change to... somewhere after the positive BPM change. To my knowledge, this exploit no longer works in StepMania 5, in part because the behavior is now officially supported through the WARPS timing data property. However, the StepMania editor still supports the legacy hack, converting any warps in the internal SSC data to negative BPMs when saving an SM file. This not only means that simfiles with warps created in SM5 will still work in 3.9, but that old files from the 3.9 era can be edited in SM5 non-destructively.

    To achieve feature parity, simfile.convert.sm_to_ssc should convert negative BPMs to warps, and simfile.convert.ssc_to_sm should do the opposite (only for simfile warps - warps in the chart timing will raise an exception by default).

    enhancement 
    opened by garcia 0
Releases(v2.1.1)
  • v2.1.1(Nov 26, 2022)

    Two bugs in simfile 2.1.0’s SSC implementation broke multi-value properties, causing them to be truncated or mangled past the first value. This release fixes these issues:

    1. When opening an SSC file, the DISPLAYBPM and ATTACKS properties of both simfiles and charts no longer stop parsing at the first :. For DISPLAYBPM, this meant a BPM range of 120:240 would have been incorrectly parsed as a static BPM of 120. ATTACKS were completely broken as they use colon as a separator.
    2. The aforementioned properties are now correctly serialized from SSCChart; previously, they would have been escaped with backslashes. This bug had the same effects described above, but only affected manual assignment of multi-value properties (e.g. chart.displaybpm = "120:240") since the first bug shadowed this bug during deserialization.
    Source code(tar.gz)
    Source code(zip)
  • v2.1.0(Aug 1, 2022)

    About

    This is the v2.1.0 release of simfile for Python 3. This is a feature release primarily focused on new abstractions around filesystem traversal & asset discovery for simfiles. It also includes some critical bugfixes & significant performance boosts, mostly by upgrading msdparser to its new major release v2.0.0.

    Up-to-date documentation for this release can be found on simfile.readthedocs.io.

    Filesystem traversal

    The new simfile.dir module offers SimfileDirectory and SimfilePack classes for nagivating simfile filesystem structures:

    from simfile.dir import SimfilePack
    
    pack = SimfilePack(R"C:\StepMania\Songs\My Pack")
    for simfile_dir in pack.simfile_dirs():
        print("Simfile paths: ", simfile_dir.sm_path, simfile_dir.ssc_path)
        sim = simfile_dir.open()
        print("Title:", sim.title)
    

    Additionally, the top-level simfile module now offers opendir() and openpack() functions as simplified interfaces to the simfile.dir API:

    import simfile
    
    for sim, filename in simfile.openpack(R"C:\StepMania\Songs\My Pack"):
        print(f"Loaded {sim.title} from {filename}")
    

    These new features aren't limited to the OS filesystem, either. PyFilesystem2 has been integrated throughout this library’s filesystem interactions, enabling OS and non-OS filesystems to be traversed using the same code. All functions, methods, and constructors that lead to filesystem interactions now have an optional filesystem parameter for specifying a PyFS filesystem object. When omitted, the filesystem defaults to the native OS filesystem as before.

    This means you can open a ZIP file (or any other supported filesystem) as a SimfileDirectory or SimfilePack, without needing to extract to disk:

    import simfile
    from fs.zipfs import ZipFS
    
    zip_fs = ZipFS(R"C:\Users\micro\Downloads\Coconut [13].zip")
    sim, filename = simfile.opendir("Coconut", filesystem=zip_fs)
    print(f"Loaded {sim.title} from {filename} inside ZIP")
    

    Asset discovery

    The new simfile.assets module provides an Assets class that can reliably discover paths to simfile assets, even if they’re not specified in the simfile. This functionality is also accessible through SimfileDirectory's assets() method.

    from simfile.dir import SimfileDirectory
    
    simfile_dir = SimfileDirectory(R"C:\StepMania\Songs\My Pack\My Song")
    assets = simfile_dir.assets()
    assert assets.music, "No music file"
    with open(assets.music, "rb") as audio_file:
        ...
    

    Assets include the song file (music) and graphics files (banner, background, cdtitle, jacket, cdimage, disc). All paths are absolute and normalized, and they should match the assets loaded by StepMania in virtually all cases.

    DisplayBPM ergonomics

    The DisplayBPM classes now all expose the same four properties; the ones that don’t apply to a particular class return None. This enables you to handle all three cases without having to import the types for isinstance checks. Refer to "Getting the displayed BPM" for more details.

    msdparser upgrade

    simfile's dependency on msdparser has been upgraded to v2.0.0, a major release that corrects how backslashes \ and colons : are parsed. These fixes apply to both reading and writing simfiles. From the perspective of client code, all you need to know is that the values you get are always unescaped: #TITLE:rE\:Voltagers; parses to a title property with value rE:Voltagers, and serializing it back to MSD adds the necessary \ before the colon in the title automatically.

    Additionally, msdparser v2.0.0 parses large documents up to 10 times faster than before!

    Note: if you get dependency errors when trying to upgrade simfile, try removing msdparser as an explicit dependency to allow it to cross the major version.

    Miscellaneous bugfixes

    • The charts property on simfiles is now writable, meaning the list of charts can be overwritten directly (not just added to / removed from).
    • sm_to_ssc() no longer produces invalid output when there are negative BPMs or stops in the timing data. (It throws NotImplementedError as a temporary stopgap. In the future, negative timing data will be converted to warps, as StepMania does automatically.)
    • Various type annotations have been improved throughout the library. In particular, Iterator input arguments have been replaced with Iterable so that you don’t need to wrap them in iter(...) to suppress type errors from static analyzers.

    Documentation

    In addition to tutorials & API docs, now you can learn by example! This page provides recipes & full scripts that demonstrate correct & type-checked library usage.

    Many other pages & API docstrings were updated for clarity & precision.


    Questions?

    Use the Discussions tab in this repository if you have questions about how to use the simfile library or ideas for new features! Holding these discussions on the open web fosters communication across a broader community of open-source enthusiasts than Discord can offer.

    Credits

    Thanks to @bkirz, @telperion, and an anonymous contributor for their input on the API additions & enhancements for this release.

    This project wouldn't exist were it not for the free creative work of hundreds of stepartists & open-source software enthusiasts. Thank you very much for your best dance!

    Source code(tar.gz)
    Source code(zip)
  • v2.0.1(Apr 24, 2022)

Owner
ash garcia
ash garcia
A YAML validator for Programming Historian lessons.

phyaml A simple YAML validator for Programming Historian lessons. USAGE: python3 ph-lesson-yaml-validator.py lesson.md The script automatically detect

Riva Quiroga 1 Nov 07, 2021
Sync any your configuration file to remote. Currently only support gist.

Sync your configuration to remote, such as vimrc. You can use EscSync to manage your configure of editor, shell, etc.

Me1onRind 0 Nov 21, 2022
A small example project for efficiently configuring a Python application with YAMLs and the CLI

Hydra Example Project for Python A small example project for efficiently configuring a Python application with YAMLs and the CLI. Why should I care? A

Florian Wilhelm 4 Dec 31, 2022
Config files for my GitHub profile.

Hacked This is a python base script from which you can hack or clone any person's facebook friendlist or followers accounts which have simple password

2 Dec 10, 2021
A modern simfile parsing & editing library for Python 3

A modern simfile parsing & editing library for Python 3

ash garcia 38 Nov 01, 2022
Config files for my GitHub profile.

Config files for my GitHub profile.

Lukas Sales 7 May 17, 2022
A helper for organizing Django project settings by relying on well established programming patterns.

django-configurations django-configurations eases Django project configuration by relying on the composability of Python classes. It extends the notio

Jazzband 955 Jan 05, 2023
This Ivy plugin adds support for TOML file headers.

This Ivy plugin adds support for TOML file headers as an alternative to YAML.

Darren Mulholland 1 Nov 09, 2021
Pydantic-ish YAML configuration management.

Pydantic-ish YAML configuration management.

Dribia Data Research 18 Oct 27, 2022
Yamale (ya·ma·lē) - A schema and validator for YAML.

Yamale (ya·ma·lē) ⚠️ Ensure that your schema definitions come from internal or trusted sources. Yamale does not protect against intentionally maliciou

23andMe 534 Dec 21, 2022
Python 3+ compatible port of the configobj library

configobj Python 3+ compatible port of the configobj library. Documentation You can find a full manual on how to use ConfigObj at readthedocs. If you

Differently Sized Kittens 288 Dec 14, 2022
Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards and optional settings files.

Organize Django settings into multiple files and directories. Easily override and modify settings. Use wildcards in settings file paths and mark setti

Nikita Sobolev 942 Jan 05, 2023
Django-environ allows you to utilize 12factor inspired environment variables to configure your Django application.

Django-environ django-environ allows you to use Twelve-factor methodology to configure your Django application with environment variables. import envi

Daniele Faraglia 2.7k Jan 03, 2023
Dynamic Django settings.

Constance - Dynamic Django settings A Django app for storing dynamic settings in pluggable backends (Redis and Django model backend built in) with an

Jazzband 1.5k Jan 04, 2023
Simple dataclasses configuration management for Python with hocon/json/yaml/properties/env-vars/dict support.

Simple dataclasses configuration management for Python with hocon/json/yaml/properties/env-vars/dict support, based on awesome and lightweight pyhocon parsing library.

Teo Stocco 62 Dec 23, 2022
Python Marlin Configurator to make valid configuration files to be used to compile Marlin with.

marlin-configurator Concept originally imagined by The-EG using PowerShell Build Script for Marlin Configurations The purpose of this project is to pa

DevPeeps 2 Oct 09, 2021
Kubernates Config Manager

Kubernates Config Manager Sometimes we need manage more than one kubernates cluster at the same time. Switch cluster configs is a dangerous and troubl

周文阳 3 Jan 10, 2022
Load Django Settings from Environmental Variables with One Magical Line of Code

DjEnv: Django + Environment Load Django Settings Directly from Environmental Variables features modify django configuration without modifying source c

Daniel J. Dufour 28 Oct 01, 2022
Apt2sbom python package generates SPDX or YAML files

Welcome to apt2sbom This package contains a library and a CLI tool to convert a Ubuntu software package inventory to a software bill of materials. You

Eliot Lear 15 Nov 13, 2022
An application pulls configuration information from JSON files generated

AP Provisioning Automation An application pulls configuration information from JSON files generated by Ekahau and then uses Netmiko to configure the l

Cisco GVE DevNet Team 1 Dec 17, 2021