Public API

The following are the functions that make up the public API of mkname.

Name Generation and Selection

These functions generate names using the data in the names database. They handle gathering the name data, reading the configuration, generating the name, and simple modification <simple_mod>.

mkname.create_compound_name(num_names: int = 1, mod: Callable[[str], str] | None = None, source: str | None = None, culture: str | None = None, date: int | None = None, gender: str | None = None, kind: str | None = None, cfg_path: Path | str | None = None, db_path: Path | str | None = None) list[str][source]

Generate a name by combining two random names.

Parameters:
  • num_names – (Optional.) The number of names to create. Defaults to one.

  • mod – (Optional.) A simple modification function for modifying the created names. Defaults to not modifying the names.

  • source – (Optional.) Limit the names used to the given source Defaults to all sources.

  • culture – (Optional.) Limit the names used to the given culture Defaults to all cultures.

  • date – (Optional.) Limit the names used to the given date Defaults to all dates.

  • gender – (Optional.) Limit the names used to the given gender Defaults to all genders.

  • kind – (Optional.) Limit the names used to the given kind Defaults to all kinds.

  • cfg_path – (Optional.) The path to a configuration file. Defaults to searching for config files.

  • db_path – (Optional.) The path to a names database. Defaults to searching for the database.

Returns:

A list object.

Return type:

list

Usage:

To generate a compound name:

>>> create_compound_name()
['Sethel']

To generate three compound names:

>>> create_compound_name(3)
['Herika', 'Betty', 'Warthur']

To force mkname.create_compound_name() to use a custom names database you built. It will also use this database if it’s the first found during a search, but this will override that search:

>>> create_compound_name(db_path='tests/data/names.db')
['Tam']

To force mkname.create_compound_name() to use a custom configuration you built. It will also use this configuration if it’s the last found during a search, but this will override that search. This can be used to change how mkname.create_compound_name() combines the names:

>>> create_compound_name(cfg_path='tests/data/test_config_full.toml')
['Haffles']

To generate a name from only male given names:

>>> create_compound_name(gender='male', kind='given')
['Llike']
mkname.create_syllable_name(num_syllables: int, num_names: int = 1, mod: Callable[[str], str] | None = None, source: str | None = None, culture: str | None = None, date: int | None = None, gender: str | None = None, kind: str | None = None, cfg_path: Path | str | None = None, db_path: Path | str | None = None) list[str][source]

Generate a name by combining syllables from random names.

Parameters:
  • num_syllables – The number of syllables in the creeated names.

  • num_names – (Optional.) The number of names to create. Defaults to one.

  • mod – (Optional.) A simple modification function for modifying the created names. Defaults to no modifying the names.

  • source – (Optional.) Limit the names used to the given source Defaults to all sources.

  • culture – (Optional.) Limit the names used to the given culture Defaults to all cultures.

  • date – (Optional.) Limit the names used to the given date Defaults to all dates.

  • gender – (Optional.) Limit the names used to the given gender Defaults to all genders.

  • kind – (Optional.) Limit the names used to the given kind Defaults to all kinds.

  • cfg_path – (Optional.) The path to a configuration file. Defaults to searching for config files.

  • db_path – (Optional.) The path to a names database. Defaults to searching for the database.

Returns:

A list object.

Return type:

list

Usage:

To generate a three syllable name:

>>> create_syllable_name(3)
['Yerethar']

To generate three compound names:

>>> create_syllable_name(3, num_names=3)
['Wilhurgar', 'Bassjuane', 'Bertollan']

To force mkname.create_syllable_name() to use a custom names database you built. It will also use this database if it’s the first found during a search, but this will override that search:

>>> create_syllable_name(3, db_path='tests/data/names.db')
['Spamlesham']

To force mkname.create_syllable_name() to use a custom configuration you built. It will also use this configuration if it’s the last found during a search, but this will override that search. This can be used to change how mkname.create_compound_name() combines the names:

>>> path = 'tests/data/test_config_full.toml'
>>> create_syllable_name(3, cfg_path=path)
['Spamhamspam']

To generate a four syllable name from only male given names:

>>> create_syllable_name(4, gender='male', kind='given')
['Hontinryal']
mkname.pick_name(num_names: int = 1, mod: Callable[[str], str] | None = None, source: str | None = None, culture: str | None = None, date: int | None = None, gender: str | None = None, kind: str | None = None, cfg_path: Path | str | None = None, db_path: Path | str | None = None) list[str][source]

Pick random names.

Parameters:
  • num_names – (Optional.) The number of names to create. Defaults to one.

  • mod – (Optional.) A simple modification function for modifying the created names. Defaults to no modifying the names.

  • source – (Optional.) Limit the names used to the given source Defaults to all sources.

  • culture – (Optional.) Limit the names used to the given culture Defaults to all cultures.

  • date – (Optional.) Limit the names used to the given date Defaults to all dates.

  • gender – (Optional.) Limit the names used to the given gender Defaults to all genders.

  • kind – (Optional.) Limit the names used to the given kind Defaults to all kinds.

  • cfg_path – (Optional.) The path to a configuration file. Defaults to searching for config files.

  • db_path – (Optional.) The path to a names database. Defaults to searching for the database.

Returns:

A list object.

Return type:

list

Usage:

To select a name:

>>> pick_name()
['Sawyer']

To pick three names:

>>> pick_name(3)
['Ethel', 'Harper', 'Erika']

To force mkname.pick_name() to use a custom names database you built. It will also use this database if it’s the first found during a search, but this will override that search:

>>> pick_name(db_path='tests/data/names.db')
['ham']

To force mkname.pick_name() to use a custom configuration you built. It will also use this configuration if it’s the last found during a search, but this will override that search:

>>> path = 'tests/data/test_config_full.toml'
>>> pick_name(cfg_path=path)
['spam']

To pick a name from only male given names:

>>> pick_name(gender='male', kind='given')
['Clarence']

Manually Configured Generation and Selection

The following functions can also generate names, but they require a little more work on your part to manage the configuration. Only use these if, for some reason, you need to get between the process of loading the configuration or names from the names database and the generation of the name:

mkname.build_compound_name(names: Sequence[Name], consonants: Sequence[str] = 'bcdfghjklmnpqrstvwxz', vowels: Sequence[str] = 'aeiouy') str[source]
mkname.build_from_syllables(num_syllables: int, names: Sequence[Name], consonants: Sequence[str] = 'bcdfghjklmnpqrstvwxz', vowels: Sequence[str] = 'aeiouy') str[source]
mkname.select_name(names: Sequence[Name]) str[source]

Name Listing

The following function will list the names in the current names database.

mkname.list_names(source: str | None = None, culture: str | None = None, date: int | None = None, gender: str | None = None, kind: str | None = None, cfg_path: Path | str | None = None, db_path: Path | str | None = None) list[str][source]

List names in the names database.

Parameters:
  • num_names – (Optional.) The number of names

  • source – (Optional.) Limit the names used to the given source Defaults to all sources.

  • culture – (Optional.) Limit the names used to the given culture Defaults to all cultures.

  • date – (Optional.) Limit the names used to the given date Defaults to all dates.

  • gender – (Optional.) Limit the names used to the given gender Defaults to all genders.

  • kind – (Optional.) Limit the names used to the given kind Defaults to all kinds.

  • cfg_path – (Optional.) The path to a configuration file. Defaults to searching for config files.

  • db_path – (Optional.) The path to a names database. Defaults to searching for the database.

Returns:

A list object.

Return type:

list

Usage:

To list all the names in the default names database:

>>> list_names()
['Noah', 'Liam', 'Jacob', 'Will...

To list all the names in a custom names database. You can also list the names in a custom database if it is the first found during the database search, but this will override that search:

>>> list_names(db_path='tests/data/names.db')
['spam', 'ham', 'tomato'...

To force mkname.list_names() to use a custom configuration you built. It will also use this configuration if it’s the last found during a search, but this will override that search.

>>> list_names(cfg_path='tests/data/test_config_full.toml')
['spam', 'ham', 'tomato'...

To list the male given names:

>>> list_names(gender='male', kind='given')
['Noah', 'Liam', 'Jacob'...

Modifying Names

Functions for modifying names after they’ve been generated.

Simple Mods

Simple mods only require one parameter: the name to modify. This makes them a bit limited in what they do, but it’s easier to call them from the command line.

mkname.double_vowel(name: str)[source]

Double a vowel within the name, like what with that popular Star Wars™ franchise the kids are talking about.

Parameters:

name – The name to modify.

Returns:

A str object.

Return type:

str

Usage:

>>> name = 'Bacon'
>>> double_vowel(name)
'Baacon'
mkname.garble(name: str)[source]

Garble some characters in the name by base 64 encoding them.

Parameters:

name – The name to modify.

Returns:

A str object.

Return type:

str

Usage:

>>> name = 'Eggs'
>>> garble(name)
'Rqggs'
mkname.make_scifi(name: str) str[source]

A simple version of mkname.mod.add_scifi_letters().

Parameters:

name – The name to modify.

Returns:

A str object.

Return type:

str

Usage:

>>> name = 'Eggs'
>>> make_scifi(name)
'Keggs'
mkname.vulcanize(name: str) str[source]

Add prefixes to names that are similar to the prefixes seen in Vulcan characters in the Star Trek™ franchise.

Parameters:

name – The name to modify.

Returns:

A str object.

Return type:

str

Usage:

>>> name = 'Bacon'
>>> vulcanize(name)
"T'Bacon"

Registration

Simple mods can be registered for use in the mkname.mods registry by using the mkname.simple_mods decorator.

class mkname.simple_mod(key: str)[source]

A decorator for registering a simple modifies to mkname.mods.

Parameters:

key – The dict key the mod will be registered under.

Returns:

A function object.

Return type:

function

Usage:

You can add a Simple Mods you create to the mkname.mods registery by using simple_mod as a decorator for that function. You can then access that modifier from the mkname.mods registry withe its key:

@simple_mod('spam')
def spam(name):
    return f'SPAM {name} SPAM!'

mods['spam']('Graham') == 'SPAM Graham SPAM!'
True

Complex Mods

Any mod that requires multiple parameters is a complex mod. These allow more flexible behavior but cannot be used directly through the mkname command line tool.

mkname.add_letters(name: str, letters: str = 'kqxz', vowels: str = 'aeiouy') str[source]

Add one of the given letters to a name.

Parameters:
  • name – The name to modify.

  • letters – The letters to add for the modification.

  • vowels – The letters to define as vowels.

Returns:

A str object.

Return type:

str

Usage:

>>> name = 'Eggs'
>>> add_letters(name)
'Keggs'

In most cases, the function behaves like the given letters are consonants. While it will replace consonants with the letter, it will often try to put a letter before or after a vowel. This means you can alter the behavior by passing different values to the letters and vowels.:

>>> # Treat 'e' as a consonant and don't use 'k'.
>>> letter = 'qxz'
>>> vowels = 'aiou'
>>> name = 'Eggs'
>>> add_letters(name, letter, vowels)
'Eggz'
mkname.add_punctuation(name: str, punctuation: Sequence[str] = "'-.?!/:@+|•", cap_before: bool = True, cap_after: bool = True, index: int | None = None) str[source]

Add a punctuation mark to the name.

Parameters:
  • name – The name to modify.

  • punctuation – (Optional.) The punctuation marks to choose from. Defaults to the default set of punctuation marks in mkname.constants.

  • cap_before – (Optional.) Whether the first letter of the substring before the punctuation mark should be capitalized. Defaults to capitalizing.

  • cap_after – (Optional.) Whether the first letter after the punctuation mark should be capitalized. Defaults to capitalizing.

  • index – (Optional.) Where to insert the punctuation. Defaults to picking an index at random.

Returns:

A str object.

Return type:

str

Usage:

>>> # Seed the RNG to make the example predictable. Don't do
>>> name = 'eggs'
>>> add_punctuation(name)
'E|Ggs'

The cap_before and cap_after parameters set whether the substrings before or after the added punctuation should be capitalized. It defaults to capitalizing them both:

>>> name = 'eggs'
>>> add_punctuation(name, cap_before=False)
'eg@Gs'
>>>
>>> yop.random.seed('spam123')
>>> name = 'eggs'
>>> add_punctuation(name, cap_after=False)
'E|ggs'

If you want to specify were the punctuation goes, you can use the index parameter. The punctuation parameter also allows you to specify what punctuation is allowed:

>>> name = 'eggs'
>>> punctuation = ':'
>>> index = 2
>>> add_punctuation(name, punctuation, index=index)
'Eg:Gs'
mkname.compound_names(mod_name: str, root_name: str, consonants: Sequence[str] = 'bcdfghjklmnpqrstvwxz', vowels: Sequence[str] = 'aeiouy') str[source]

Construct a new name using the parts of two names.

Parameters:
  • names – A list of Name objects to use for constructing the new name.

  • consonants – (Optional.) The characters to consider as consonants.

  • vowels – (Optional.) The characters to consider as vowels.

Returns:

A str object.

Return type:

str

Usage:

>>> # Generate the name.
>>> mod_name = 'Spam'
>>> base_name = 'Eggs'
>>> compound_names(mod_name, base_name)
'Speggs'

The function takes into account whether the starting letter of each name is a vowel or a consonant when determining how to create the name. You can affect this by changing which letters it treats as consonants or vowels:

>>> # Treat 'e' as a consonant and 'g' as a vowel.
>>> consonants = 'bcdfhjklmnpqrstvwxze'
>>> vowels = 'aioug'
>>>
>>> # Generate the name.
>>> mod_name = 'Spam'
>>> base_name = 'Eggs'
>>> compound_names(mod_name, base_name, consonants, vowels)
'Spggs'
mkname.double_letter(name: str, letters: Sequence[str] = '') str[source]

Double a letter in the name.

Parameters:
  • name – The name to modify.

  • letters – (Optional.) The letters allowed to double. This defaults to all letters in the name.

Returns:

A str object.

Return type:

str

Usage:

>>> name = 'Bacon'
>>> double_letter(name)
'Baacon'

You can limit the numbers that it will double by passing a string of valid letters:

>>> # The valid letters to double.
>>> letters = 'bcn'
>>>
>>> name = 'Bacon'
>>> double_letter(name, letters)
'Baccon'
mkname.translate_characters(name: str, char_map: Mapping[str, str], casefold: bool = True) str[source]

Translate characters in the name to different characters.

Parameters:
  • name – The name to modify.

  • char_map – A translation map for the characters in the name. The keys are the original letters and the values are the characters to change them to.

  • casefold – Whether case should be ignored for the transform.

Returns:

A str object.

Return type:

str

Usage:

>>> # The translation map is a dict.
>>> char_map = {'s': 'e', 'p': 'g', 'm': 's'}
>>>
>>> name = 'spam'
>>> translate_characters(name, char_map)
'egas'

Data Gathering

The following is a description of the API for working directly with a names database.

Read Data

The following functions all read records in the database. While you can manually pass a database connection to these functions if you ever need to, they will create their own connection if you don’t.

mkname.get_cultures(con: Connection) tuple[str, ...][source]

Get a list of unique cultures in the database.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

A tuple of Name objects.

Return type:

tuple

Usage:

@makes_connection allows you to pass the path of the database file rather than a connection:

>>> loc = 'tests/data/names.db'
>>> get_cultures(loc)
('bacon', 'pancakes', 'porridge')
mkname.get_dates(con: Connection) tuple[str, ...][source]

Get a list of unique dates in the database.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

A tuple of Name objects.

Return type:

tuple

Usage:

@makes_connection allows you to pass the path of the database file rather than a connection:

>>> loc = 'tests/data/names.db'
>>> get_dates(loc)
(1970, 2000)
mkname.get_genders(con: Connection) tuple[str, ...][source]

Get a list of unique genders in the database.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

A tuple of Name objects.

Return type:

tuple

Usage:

@makes_connection allows you to pass the path of the database file rather than a connection:

>>> loc = 'tests/data/names.db'
>>> get_genders(loc)
('sausage', 'baked beans')
mkname.get_kinds(con: Connection) tuple[str, ...][source]

Get a list of unique kinds in the database.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

A tuple of Name objects.

Return type:

tuple

Usage:

@makes_connection allows you to pass the path of the database file rather than a connection:

>>> loc = 'tests/data/names.db'
>>> get_kinds(loc)
('given', 'surname')
mkname.get_names(con: Connection, source: str | None = None, culture: str | None = None, date: int | None = None, gender: str | None = None, kind: str | None = None) tuple[Name, ...][source]

Deserialize the names from the database.

Parameters:
  • con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

  • source – (Optional.) A filtering value for the source field. Defaults to a wildcard.

  • culture – (Optional.) A filtering value for the culture field. Defaults to a wildcard.

  • date – (Optional.) A filtering value for the date field. Defaults to a wildcard.

  • gender – (Optional.) A filtering value for the gender field. Defaults to a wildcard.

  • kind – (Optional.) A filtering value for the kind field. Defaults to a wildcard.

Returns:

A tuple of Name objects.

Return type:

tuple

Usage:

@makes_connection allows you to pass the path of the database file rather than a connection:

>>> loc = 'tests/data/names.db'
>>> get_names(loc)
(Name(id=1, name='spam', source='eggs', ... kind='given'))
mkname.get_names_by_kind(con: Connection, kind: str) tuple[Name, ...][source]

Deserialize the names from the database.

Parameters:
  • con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

  • kind – The kind of names to return. By default, this is either ‘given’ or ‘surname’, but if you have a custom database you can add other types.

Returns:

A tuple of Name objects.

Return type:

tuple

Usage:

@makes_connection allows you to pass the path of the database file rather than a connection:

>>> loc = 'tests/data/names.db'
>>> kind = 'given'
>>> get_names_by_kind(loc, kind)
(Name(id=1, name='spam', source='eggs', ... kind='given'))
mkname.get_sources(con: Connection) tuple[str, ...][source]

Get a list of unique sources in the database.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

A tuple of Name objects.

Return type:

tuple

Usage:

@makes_connection allows you to pass the path of the database file rather than a connection:

>>> loc = 'tests/data/names.db'
>>> get_sources(loc)
('eggs', 'mushrooms')

Database Administration

The following functions are used to create and update data in a names database or otherwise administer those databases.

Connecting to the Database

For the most part, functions that need to connect to a names database should manage that connection through one of these decorators. Specifically, anything that just reads should use mkname.db.makes_connection(), and anything that needs to create, update, or delete should use mkname.db.protects_connection().

mkname.db.makes_connection(fn: Callable) Callable[source]

A decorator that manages a database connection for the decorated function.

mkname.db.protects_connection(fn: Callable) Callable[source]

A decorator that manages a database connection for the decorated function and prevents implicit connection to the default database.

However, if you want to make a manual connection to the database, you can use the following functions to open and close the connection.

mkname.db.connect_db(location: str | Path) Connection[source]

Connect to the database.

Parameters:

location – The path to the database file.

Returns:

A :class:sqlite3.Connection object.

Return type:

sqlite3.Connection

Usage:

>>> loc = 'tests/data/names.db'
>>> query = 'select name from names where id = 1;'
>>> con = connect_db(loc)
>>> result = con.execute(query)
>>> tuple(result)
(('spam',),)
>>> disconnect_db(con)
mkname.db.disconnect_db(con: Connection, override_commit: bool = False) None[source]

Disconnect from the database.

Parameters:
  • con – A database connection.

  • override_commit – (Optional.) Whether to override errors due to uncommitted changes. Defaults to False.

Returns:

None.

Return type:

:class:NoneType

See mkname.db.connect_db() for usage.

Create and Update Data

The following functions will create and update records in the database. While you can manually pass a database connection to these functions if you ever need to, they will create their own connection if you don’t.

mkname.db.get_max_id(con: Connection) int[source]

Get the highest ID in the database.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

An int object.

Return type:

tuple

mkname.db.add_name_to_db(con: Connection, name: Name, update: bool = False) None[source]

Add a name to the given database. If the name has the same ID as a name already in the database, update the values in the database to match the values for the given name.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

None.

Return type:

NoneType

mkname.db.add_names_to_db(con: Connection, names: Sequence[Name], update: bool = False) None[source]

Add multiple names to the database. If any of those names have the same ID as names already existing in the database, update the values for those names in the database to the values for the given names.

Parameters:

con – The connection to the database. It defaults to creating a new connection to the default database if no connection is passed.

Returns:

None.

Return type:

NoneType

Database Creation

The following functions create new databases.

mkname.db.duplicate_db(dst_path: Path | str) None[source]

Create a duplicate of the names.db database.

Parameters:

dst_path – The path to copy the database into.

Returns:

None.

Return type:

NoneType

mkname.db.create_empty_db(path: Path | str) None[source]

Create an empty names database.

Parameters:

path – Where to create the database.

Returns:

None.

Return type:

NoneType

Configuration API

The following are the basic initialization functions for mkname.

mkname.get_config(path: Path | str | None = None) dict[str, dict[str, str]][source]

Get the configuration.

Parameters:

location – (Optional.) The path to the configuration file. If no path is passed or the passed path doesn’t exist, it will fall back to a series of other files. See “Loading Configuration”.

Returns:

A dict object.

Return type:

dict

Usage:

>>> loc = 'tests/data/test_load_config.conf'
>>> get_config(loc)
{'mkname': {'consonants': 'bcd', 'db_path':...
mkname.get_db(path: Path | str | None = None, conf_path: Path | str | None = None) Path[source]

Get the path to the names database.

Parameters:

path – The path of the names database.

Returns:

The path to the names database as a pathlib.Path.

Return type:

pathlib.Path

Usage:

>>> loc = 'src/mkname/data/names.db'
>>> get_db(loc)
PosixPath('src/mkname/data/names.db')

Database Structure

The names database is a sqlite3 database with a table named ‘names’. The names table has the following columns:

  • id: A unique identifier for the name.

  • name: The name.

  • source: The URL where the name was found.

  • culture: The culture or nation the name is tied to.

  • date: The approximate year the name is tied to.

  • kind: A tag for how the name is used, such as a given name or a surname.