In Python, generate a random file name with secrets.token_hex(), keep the extension separate, and create the path with exclusive mode (x) so an existing file is not overwritten.

A random name is useful for uploads, exports, caches, and test fixtures, but randomness solves only the naming part. The path still needs a controlled directory, the extension should be deliberate, and the write should fail safely if another process has already claimed the name. The examples below cover permanent names, temporary files, and a browser-local dummy payload for upload testing.

how to generate random file name in python
How to Generate a Random File Name in Python

Choose the right source of randomness

Use cryptographic randomness when the name may be exposed to users or an attacker. Python's secrets module is the clearest choice for an unpredictable token. A UUID4 value is convenient when you also want a standard identifier shape. The general-purpose random module is suitable for non-sensitive sample labels, but it is not the right foundation for an unguessable upload name.

Choose the approach based on the job rather than on the amount of code:

Approach Good fit Important limitation
secrets.token_hex() Unpredictable upload, export, or cache names Returns hexadecimal text, so an approved extension must be added separately
uuid.uuid4().hex Identifiers that benefit from UUID formatting Still needs controlled path handling and collision-safe creation
random.choices() Non-sensitive fixtures and examples Not intended to resist prediction
tempfile.NamedTemporaryFile A real temporary file with a managed path You must decide when the file should be removed and reopened

No random-name function can promise that a path is unused before the file is created. Another process can claim a name between generation and opening, so collision-safe creation matters even with a long random token.

Build a random filename in Python

Keep the random component and extension under code control. Do not splice unrestricted user text into a path. A short fixed prefix can describe the record type, while a random token reduces guessing and collision risk.

  1. Choose a fixed prefix that describes the file, such as upload, export, or cache.
  2. Generate the unpredictable component with secrets.token_hex() or uuid4().hex.
  3. Append an approved extension and keep the result a basename under a controlled destination directory.

The simplest secure-token pattern is:

  • Import: from secrets import token_hex
  • Token: token = token_hex(16)
  • Filename: filename = f"upload-{token}.bin"

This code generates a filename but does not create a file. The hexadecimal token contains no path separators, and the suffix is fixed, so the random value cannot turn into a directory path. For a readable identifier, secrets.choice() can select from an allowlist of letters and digits, but the token should still match the application's collision and threat model. A random name is not an authorization mechanism and should not decide whether a user may read a file.

When UUID semantics are useful, the equivalent pattern is simpler:

  • Import: from uuid import uuid4
  • Filename: filename = f"{uuid4().hex}.csv"

The extension is only a label. A name ending in .csv does not make the file CSV data, so write the appropriate content or use the extension your receiving system explicitly expects.

Write the file without overwriting data

Generating a candidate name does not reserve it. Use exclusive creation and retry when the path already exists:

  1. Select or create the intended output directory.
  2. Generate a fresh candidate name inside a loop.
  3. Open the path with binary exclusive mode, xb.
  4. Catch FileExistsError and try another candidate; use a bounded retry count in a service.

The essential loop is:

  • Imports: from pathlib import Path; from secrets import token_hex
  • Directory: output = Path("output")
  • Prepare: output.mkdir(exist_ok=True)
  • Loop: while True:
  • Candidate: filename = f"upload-{token_hex(16)}.bin"
  • Path: path = output / filename
  • Create: with path.open("xb") as file:
  • Write: file.write(b"test payload")
  • Success: break
  • Collision: except FileExistsError: continue

The x in xb means create exclusively. It fails when the path exists instead of truncating it, whereas mode w would overwrite existing bytes. This matters when two workers generate names concurrently. Open with text-mode x instead when writing strings, and add a finite retry limit so repeated filesystem errors do not create an endless loop.

If the application receives a filename or extension from a user, validate that component before joining it to a directory. A fixed extension allowlist is usually safer than accepting arbitrary text. Randomizing the basename does not prevent extension tricks or unsafe content.

Use Python temporary-file helpers

When the name's main job is to identify a temporary resource, tempfile.NamedTemporaryFile removes manual token construction and handles the platform-specific temporary-file details.

  • Import: from tempfile import NamedTemporaryFile
  • Create: with NamedTemporaryFile(prefix="upload-", suffix=".bin", delete=False) as file:
  • Write: file.write(b"temporary test data")
  • Path: temporary_path = file.name

The default deletion behavior removes the file when it is closed. Set delete=False when another part of the application must reopen the path after the context manager closes the handle, then remove it explicitly when finished. Pass the prefix and suffix as arguments instead of editing the generated path afterward. Use TemporaryDirectory when a group of temporary files must share one cleanup location.

Add a browser-built upload fixture

For an upload, storage, transfer, or checksum test, keep the generated identifier and the file body as separate concerns. The Dummy File Generator creates the body: a local file with an exact byte count and a defined content policy. It does not generate a Python filename, so use the name produced by your Python code when entering one.

  1. Enter a safe file name and an exact whole-number byte size from 1 through 52,428,800. The size must contain decimal digits only, with no sign, decimal point, exponent, comma, unit suffix, or surrounding whitespace.
  2. Choose zero bytes, secure random bytes, or repeated UTF-8 text. For text mode, provide a nonempty pattern no longer than 10,000 UTF-16 code units and free of unpaired Unicode surrogates.
  3. Generate the Blob, confirm the displayed exact byte summary and content policy, then download the local dummy file.
Content mode What it creates Reproducibility and boundary behavior
Zero bytes Only byte value 0x00 Deterministic and often compresses dramatically
Secure random bytes Random data from browser Web Crypto No seed is retained, so the same random file cannot be reproduced later
Repeated UTF-8 text The encoded pattern repeated toward the requested size Complete characters are used first, with ASCII spaces filling any final one-to-three bytes that cannot hold another character

Secure-random mode calls the browser's Crypto.getRandomValues API in chunks no larger than 65,536 bytes. It is useful for incompressible test data and checksum pipelines, but it is not a password generator, encryption system, or proof that the downloaded bytes remain secret after sharing.

Text mode preserves valid UTF-8 even when the requested size falls in the middle of a multi-byte character. ASCII, acc accented letters, CJK characters, and emoji do not all occupy the same number of bytes, so a pattern's displayed length is not its encoded length.

All construction and downloading happen in the current browser tab. No generated bytes, file name, or text pattern are uploaded to Lizely or sent to another service. The generator sums its parts and checks the final Blob size against the request without rounding, truncation, or sampling. The reported number is the logical byte count; file systems and transfer tools may compress zero runs or repeated text, so physical disk usage and compressed transfer size can differ.

File names are validated rather than silently sanitized. The tool rejects empty names, surrounding whitespace, path-like names, unsafe separators and lookalikes, control or invisible formatting characters, trailing dots, and Windows device names such as CON, NUL, COM1, and LPT1. An accepted name is passed unchanged to the download, although a browser may rename a same-named download. Closing or editing the page revokes the in-memory download URL, so regenerate the file if needed.

The extension does not create a real format. A name ending in .png or .pdf still contains only zeros, random bytes, or repeated text; it does not become a valid image, PDF, archive, executable, or media stream.

Validate the name before it reaches your application

Run the generated name through a short application-level checklist before using it:

  • Keep the random token and extension under trusted code control.
  • Reject empty names, dot paths, forward or backward slashes, control characters, and Windows device names.
  • Use an extension allowlist and validate the uploaded content separately from the filename.
  • Join the basename to an intended directory and create it with exclusive mode.
  • Keep the filename and expected byte count in test metadata so the application can assert both conditions.

For an upload fixture, generate the filename in Python, enter that same safe name in the browser generator, choose the content mode that matches the test, and confirm the exact byte summary before downloading. Keep the payload available locally and use it only in authorized upload, storage, or transfer tests. Random bytes suit pipelines that calculate a checksum after generation; zero or repeated text is better when the fixture itself must be reproducible.