Skip to main content

todo

Project description

normalize-json

Install

$ pip install normalize-json

CLI

$ python -m normalize-json -h

Use cases

This library can be used to normalize several API specs into a single standardized structure. Click here to view some examples.

Usage

Mapping

Mapping is the schema object you use to specify how your properties should be converted.

Suppose you have the following structured data:

{
  "skills": [
    "smartest programmer that has ever lived",
    "high priest",
    "builder of the temple of god"
  ],
  "nested_prop": {
    "name": "Terry Davis",
    "age": 50
  }
}

An example mapping could be as following. In this example we'll rename the .nested_prop.age path to .nested_prop.years_on_earth while converting its value to string and move the .skills path to .nested_prop.skills. Notice how properties with names starting with a dot (".") will be treated as paths whereas properties without a dot in the beginning will be treated as same-level properties.

{
  "modifiers": [
    "default_null"
  ],
  "__fields": {
    "secret": {
      "map": "{{ secret.key }}"
    },
    "nested_prop": {
      "type": "object",
      "__fields": {
        "name": {
          "type": "string"
        },
        "years_on_earth": {
          "map": "age",
          "type": "string",
          "modifiers": [
            "enforce"
          ]
        },
        "mastered_skills": {
          "map": ".skills",
          "type": "string",
          "array": true
        }
      }
    }
  }
}

Running translate(sample, mapping, substitute={ 'secret.key': 'abc123' }) against it would derive the following JSON:

{
  "secret": "abc123",
  "nested_prop": {
    "name": "Terry Davis",
    "years_on_earth": "50",
    "mastered_skills": [
      "smartest programmed that has ever lived",
      "high priest",
      "builder of the temple of god"
    ]
  }
}

A minimal example is as following:

import normalize_json as normalize
import json

sample = {
  'person': {
    'name': 'João',
    'pet': {
      'name': 'Thor'
    }
  }
}

mapping = {
  '__fields': {
    'pet': {
      '__fields': {
        'name': '.person.pet.name'
      }
    }
  }
}

string_mapping = {
  '__fields': {
    'dog': 'beef',
    'bird': [
      'seeds',
      'plants'
    ]
  }
}

def output(obj):
  print(json.dumps(obj, indent=2))

def main():
  """
  {
    "person.name": "João",
    "person.pet.name": "Thor"
  }
  """
  output(normalize.flatten(sample))

  """
  {
    "pet": {
      "name": "Thor"
    }
  }
  """
  output(normalize.translate(sample, mapping))

  """
  "dog"
  """
  output(normalize.translate_string('beef', string_mapping))

  """
  "bird"
  """
  output(normalize.translate_string('seeds', string_mapping))

if __name__ == '__main__':
  main()

Types

The node accept the following Python primitive types (plus objectid and datetime):

  • object
  • string
  • datetime
  • number
  • integer
  • objectid
  • boolean

Enums

String values can be mapped using enums:

mapping: Mapping = {
  '__fields': {
    'status': {
      'enum': {
        'ativo': 'active',
        'inativo': 'inactive',
      }
    },
    'colors': {
      'array': True,
      'enum': {
        'azul': 'blue',
        'vermelho': 'red',
        'verde': 'green',
      }
    }
  }
}

sample = {
  'status': 'ativo',
  'colors': [
    'azul',
    'vermelho',
  ]
}

# { 'status': 'active', 'colors': ['blue', 'red'] }
result = normalize.translate(sample, mapping)

Modifiers

You can change the default behavior passing a array of "modifiers" in your mapping node. Those will be inherited all the way down until the "modifiers" property is overriden.

Available modifiers are:

  • strict: raise when the expected value isn't present
  • reverse: shift origin and mapped names
  • default_null: set None (or null) as the default value for absent properties
  • enforce: cast values to expected type instead of raising a TypeError

Attributes

  • array: whether the expected value is an array or not
  • trim_start: trim n characters from the beginning of the string
  • trim_end: trim n characters from the end of the string
  • pick_until: same as value.split(str)[0]

Support and contributing

You can obtain suport if you're using this library on production. Just email the author at joaosan177[at]gmail.com. You may also send PRs, just make sure to include tests and follow PEP guidelines.

Run typechecking

$ python -m pyright

Run tests

$ python -m unittest tests/*.py

License

This library is MIT licensed.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

normalize_json-0.0.19.tar.gz (8.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

normalize_json-0.0.19-py3-none-any.whl (7.7 kB view details)

Uploaded Python 3

File details

Details for the file normalize_json-0.0.19.tar.gz.

File metadata

  • Download URL: normalize_json-0.0.19.tar.gz
  • Upload date:
  • Size: 8.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.12.4

File hashes

Hashes for normalize_json-0.0.19.tar.gz
Algorithm Hash digest
SHA256 5db0d8ba28bce30468106e6952930c585e9a19e7c56f5e38e5f5962998566766
MD5 2275dc764d6eb8b5570b818af6f40f9e
BLAKE2b-256 5fb7618c78d3677635344cfb38b23707c366762fe899c2be2311494a6312fa8f

See more details on using hashes here.

File details

Details for the file normalize_json-0.0.19-py3-none-any.whl.

File metadata

File hashes

Hashes for normalize_json-0.0.19-py3-none-any.whl
Algorithm Hash digest
SHA256 e5c20230b68d3b9c859a1a22acbfc6bcfdeb50acc7dad6088c91297bb1119b5d
MD5 4dbea7b4be6239d2e388fef38c92d064
BLAKE2b-256 52733171fca3cf560aebd2de74959bed704e350b4d057044f284aa94ff96e688

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page