Skip to main content

Generate String from regex pattern

Project description

rand

Travis (.org) Coverage Status MIT license PyPI pyversions PyPI - Downloads


Random generated String from regex pattern

WARNING

The library rand is still in working-in-progress. It is subject to high possibility of API changes. Would appreciate feedback, suggestions or help.

Why?

There are lot of existing projects similar to rand, they are powerful and have similar goals and results. However most of them are old projects/non-maintained and non-MIT licenses.

This is a good opportunity for rand to be the library to help generate random data for any projects and gather all other existing libraries to be the main driver.

Install

Use pip or clone this repository and execute the setup.py file.

$ pip install rand

Usages

Basic usage rand examples

# import module
from rand import Rand

# initialise object
rnd = Rand()

# generate pattern literal
rnd.gen('koro') # ['koro']
rnd.gen('28') # ['28']
rnd.gen('a-z') # ['a-z']

# generate pattern any
rnd.gen('.') # any char in string.printable

# generate pattern branch
rnd.gen('ko|ro') # either ['ko'] or ['ro']
rnd.gen('ko|ro|ro') # either ['ko'] or ['ro']

# generate pattern in
rnd.gen('[kororo]') # either ['k'] or ['o'] or ['r']
rnd.gen('k[o]r[o]r[o]') # ['kororo']

# generate pattern repeat
rnd.gen('r{2,8}') # char r in length between 2 to 8 times

# generate pattern range
rnd.gen('[a-z]') # char between a to z

# generate pattern subpattern
rnd.gen('(ro)') # ['ro']

Providers

The library rand at core only provide random generators based on regex. Providers are built to allow extensions for rand.

Built-in Providers

There are a few built-in providers inside rand

EN Provider

This library covers most usage around English requirements.

from rand import Rand


rnd = Rand()
rnd.gen('(:en_vocal:)') # char either a, i, u, e, o

Dataset Provider

This library helps on getting data from dataset such as Python object or Database with peewee.

from rand import Rand
from rand.providers.ds import RandDatasetBaseProvider, ListDatasetTarget


# example using dict of list
db = {'names': ['test1', 'test1'], 'cities': ['test2', 'test2']}
ds = RandDatasetBaseProvider(prefix='ds', target=ListDatasetTarget(db=db))
rnd = Rand()
rnd.register_provider(ds)
rnd.gen('(:ds_get:)', ['names'])  # ['test1']
rnd.gen('(:ds_get:)', ['cities']) # ['test2']
# or, magic getattr
rnd.gen('(:ds_get_names:)-(:ds_get_cities:)') # ['test1-test2']

# example of database using peewee
from peewee import Proxy
from playhouse.sqlite_ext import CSqliteExtDatabase
from rand.providers.ds import RandDatasetBaseProvider, DBDatasetTarget
db = Proxy()
# ensure to have table with name "names", contains column at least (id, name)
db.initialize(CSqliteExtDatabase(':memory:', bloomfilter=True))
ds = RandDatasetBaseProvider(prefix='ds', target=DBDatasetTarget(db=db))
rnd = Rand()
rnd.register_provider(ds)
rnd.gen('(:ds_get:)', ['names']) # ['test']
db.close()

Integration Providers

The library rand also has integration with existing projects such as Faker. Ensure you have faker library installed.

Faker

There is super basic integration with Faker for now, soon will be more implemented.

# ensure you have Faker installed
pip install Faker
from rand import Rand


rnd = Rand()
rnd.gen('(:faker_hexify:)') # abc

Custom Parse

Extending rand is simple, there are register_parse and register_provider, both of this has special level of customisation.

Simple Register Parse

This is example of creating custom parse in simple way.

from rand import Rand

# init rand class
rnd = Rand()

# the definition
def parse_test1(pattern, opts=None):
    return 'test1'

# the registration
rnd.register_parse(name='test1', fn=parse_test1)
# test it
rnd.gen('(:test1:)')

Decorator Wrapper Register Parse

This is faster way with decorator pattern to register custom parse.

from rand import Rand

# init rand class
rnd = Rand()

# the definition
@rnd.register_parse_wrapper(name='test1')
def parse_test1(pattern, opts=None):
    return 'test1'

# test it
rnd.gen('(:test1:)')

Custom Providers

Custom provider is upper level customisation in rand, it behaves quite differently than custom parse

Simple Register Provider

Below is sample code on how to integrate an existing class definition (TestProxy) to Rand.

from rand.providers.base import RandBaseProvider
from rand import Rand

class TestProvider(RandBaseProvider):
    def _parse_fn(self, pattern, opts=None):
        return 'test'

    def parse(self, name: str, pattern: any, opts: dict):
        # name always start with _parse_[PREFIX], normalise first
        parsed_name = self.get_parse_name(name)
        if parsed_name:
            return self._parse_fn(pattern, opts)
        return None

# init rand class
rnd = Rand()
rnd.register_provider(TestProvider(prefix='test_fn'))
assert rnd.gen('(:test_fn:)') == 'test'
from rand import Rand
from rand.providers.base import RandProxyBaseProvider

# class definition
class TestProxy:
    # simple function definition to return args values
    def target(self, arg1='def1', arg2='def2'):
        return '%s-%s' % (arg1, arg2)

# init rand class
rnd = Rand()

# create proxy provider helper and register to rand
test_proxy = RandProxyBaseProvider(prefix='test', target=TestProxy())
rnd.register_provider(test_proxy)

# test
print(rnd.gen('(:test_target:)')) # ['def1-def2']
print(rnd.gen('(:test_target:)', ['ok1'])) # ['ok1-def2']
print(rnd.gen('(:test_target:)', ['ok1', 'ok2'])) # ['ok1-def2']
print(rnd.gen('(:test_target:)', [['ok1', 'ok2']])) # ['ok1-ok2']
print(rnd.gen('(:test_target:)', [['ok1', 'ok2'], 'ok3'])) # ['ok1-ok2']
print(rnd.gen('(:test_target:)', [{'arg1': 'ok1'}])) # ['ok1-def2']
print(rnd.gen('(:test_target:)', [{'arg1': 'ok1', 'arg2': 'ok2'}])) # ['ok1-ok2']

Decorator Wrapper Register Provider

This is faster way with decorator pattern to register custom provider.

from rand import Rand

# init rand class
rnd = Rand()

@rnd.register_provider_fn_wrapper(prefix='test2')
def parse_test2(pattern, opts=None):
    return 'test2'

print(rnd.gen('(:test2:)'))  # 'test2'

Different Between Custom Parser and Provider

The way rand works, register_parse taps into the core of rand, following the token from sre_parse, when the definition is returned, it is possible to return sre_parse token with existing token name or custom token which points to the custom definition.

from rand import Rand

# init rand class
rnd = Rand()

@rnd.register_parse_wrapper(name='test1')
def parse_test1(pattern, opts=None):
    return 'test1'


@rnd.register_parse_wrapper(name='test2')
def parse_test2(pattern, opts=None):
    return rnd.sre_parse_compile_parse('(:test1:)')


print(rnd.gen('(:test2:)'))  # 'test1'

Test

Run test by installing packages and run tox

$ pip install poetry tox
$ tox
$ tox -e py36 -- tests/test_ds.py

For hot-reload development coding

$ npm i -g nodemon
$ nodemon -w rand --exec python -c "from rand import Rand"

Help?

Any feedback, suggestions and integration with 3rd-party libraries can be added using PR or create issues if needed helps.

Similar Projects

List of projects similar to rand:

  • exrex: Irregular methods on regular expressions
  • xeger: Library to generate random strings from regular expressions
  • strgen: A Python module for a template language that generates randomized data

Acknowdlge Projects

List of projects that rand depends on:

  • peewee: a small, expressive orm -- supports postgresql, mysql and sqlite
  • pytest: The pytest framework makes it easy to write small tests, yet scales to support complex functional testing
  • coverage: Code coverage measurement for Python
  • pytest-cov: Coverage plugin for pytest

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

rand-0.3.0.tar.gz (14.1 kB view hashes)

Uploaded Source

Built Distribution

rand-0.3.0-py3-none-any.whl (13.1 kB view hashes)

Uploaded Python 3

Supported by

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