Token generation system in py3.7
Well, in the first place I have a question as to why you would need this specific pattern of tokens; it seems for a very specific use case.

Secondly, you use a pretty consistent naming convention in your code (which is very good), but the shortened names and abbreviations make it difficult for a person to understand your code quickly (in my opinion).



Lastly, if you are  looking for less code and more speed with the same functionality, I can propose this:

import random
import secrets
import string

FRAGMENT_ALPHABET = string.ascii_letters + string.digits
FRAGMENT_SEPARATOR_OPTIONS = ('.', '-')
FRAGMENT_MIN_LENGTH = 30
FRAGMENT_MAX_LENGTH = 34

def _generate_fragment(length: int, prepend_separator: bool):
    prefix = ''
    if prepend_separator:
        prefix = secrets.choice(FRAGMENT_SEPARATOR_OPTIONS)

    s = ''.join(
        secrets.choice(FRAGMENT_ALPHABET)
        for _ in range(length))

    return prefix + s

def token(num_parts: int = 3):
    return ''.join(
        _generate_fragment(
            length=random.randint(FRAGMENT_MIN_LENGTH, FRAGMENT_MAX_LENGTH),
            prepend_separator=i &gt; 0)          # only False for the first fragment
        for i in range(num_parts))


In this code:


In my opinion (opinions can be very subjective) the code is still readable, but has less functions and those have explicit long names, which helps users to understand it faster.
I also put some general parameters as uppercase module variables at the top of the file; this makes it easier to modify and (in my opinion) also easier to read/understand in the code.
The execution time is less. Comparing the two versions using timeit like this for both versions (with Ubuntu and Python3.6):

&gt;&gt;&gt; timeit.timeit('token()', 'from __main__ import token', number=10000)


I get these results, showing my version as faster using about 8 % less time:

Version    Time      Time comparisson
yours      2.222258   100.0 %
mine       2.060732    92.7 %