Generate String from regex pattern
Project description
rand
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
Built Distribution
File details
Details for the file rand-0.3.0.tar.gz
.
File metadata
- Download URL: rand-0.3.0.tar.gz
- Upload date:
- Size: 14.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.0.2 CPython/3.7.3 Darwin/19.4.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8c7dcdebf5ddd0088893bdf850ea62275e337a44e702927405168031c9d7ee91 |
|
MD5 | a6ccc928ba9b7fb0a6a0cbe37da669be |
|
BLAKE2b-256 | 33d012efa7230445849141029623bf64fcb7cc15f3462332b8be654d0e2be38f |
File details
Details for the file rand-0.3.0-py3-none-any.whl
.
File metadata
- Download URL: rand-0.3.0-py3-none-any.whl
- Upload date:
- Size: 13.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.0.2 CPython/3.7.3 Darwin/19.4.0
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6c0a46e2bdef2fb1b569ccf8ef3014d5c3aea5bc0092fd2d1b625f58d61390d7 |
|
MD5 | 800aa9c5790d98e2bcf972ed6f438114 |
|
BLAKE2b-256 | c975a3be8178774e475eab96b7836126cecb07b811cb12a64b6b1f29b0395916 |