{"id":2838,"library":"ulid-py","title":"ULID Python Implementation (ahawker/ulid)","description":"The `ulid-py` library (version 1.1.0) provides a minimal, self-contained Python 3 implementation of the Universally Unique Lexicographically Sortable Identifier (ULID) specification. It aims for a lightweight implementation without external dependencies. The project is currently in maintenance mode, with its last release in March 2022.","status":"maintenance","version":"1.1.0","language":"python","source_language":"en","source_url":"https://github.com/ahawker/ulid","tags":["ULID","identifier","UUID","sortable ID"],"install":[{"cmd":"pip install ulid-py","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"note":"The `ahawker/ulid` library primarily uses `ulid.new()` for generating new ULIDs, unlike other ULID implementations that might use `ULID()` directly.","wrong":"from ulid import ULID; ULID()","symbol":"new","correct":"import ulid\nulid.new()"},{"note":"Used to create a ULID from a datetime or timestamp value.","symbol":"from_timestamp","correct":"import ulid\nulid.from_timestamp(some_datetime_obj)"},{"note":"Used to create a ULID from a UUID object.","symbol":"from_uuid","correct":"import ulid\nulid.from_uuid(some_uuid_obj)"}],"quickstart":{"code":"import ulid\nimport datetime\n\n# Create a brand new ULID\nu = ulid.new()\nprint(f\"New ULID: {u}\")\nprint(f\"String representation: {str(u)}\")\n\n# Create a new ULID from an existing datetime object\ndt = datetime.datetime(1999, 1, 1, tzinfo=datetime.timezone.utc)\nu_from_dt = ulid.from_timestamp(dt)\nprint(f\"ULID from datetime: {u_from_dt}\")\n\n# Access timestamp and randomness parts\nprint(f\"Timestamp part: {u.timestamp()}\")\nprint(f\"Randomness part: {u.randomness()}\")\n\n# Convert to UUID\nimport uuid\nuuid_val = u.to_uuid()\nprint(f\"As UUID: {uuid_val}\")","lang":"python","description":"Demonstrates generating new ULIDs, creating them from existing timestamps, and accessing their components and other representations."},"warnings":[{"fix":"Ensure your project runs on Python 3.5+.","message":"Python 2 support was dropped in version 1.0.0. This library (v1.1.0) requires Python 3.5 or newer.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Always check the specific documentation for the `ulid` package you have installed and verify the GitHub repository or PyPI page to ensure you are using the intended library.","message":"Potential confusion with other Python ULID libraries. While this entry is for `ulid-py` (ahawker's implementation), there are other popular and more actively maintained libraries like `python-ulid` (mdomke's implementation) with different APIs (e.g., `ULID()` constructor vs. `ulid.new()`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Use `ulid_instance.timestamp()` and `ulid_instance.randomness()` to access these components in `ulid-py`.","message":"API differences for accessing ULID components. In `ulid-py` (ahawker), `timestamp()` and `randomness()` are methods. In some other ULID libraries, these might be properties (e.g., `ulid.timestamp`).","severity":"gotcha","affected_versions":"All versions"},{"fix":"Do not use ULIDs where cryptographic randomness is a strict requirement for security. Consider adding an additional layer of cryptographic randomness or using a UUIDv4/other cryptographically secure identifier.","message":"Security considerations when using ULIDs. Although `ulid-py` does not explicitly implement monotonic incrementing of the random component for same-millisecond generation by default (based on available documentation for this specific library), the timestamp component of ULIDs can still expose creation times. For applications requiring strong unpredictability (e.g., password reset tokens), a cryptographically secure random identifier might be more appropriate.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.1.0':11 '2022':52 '3':19 'ahawker/ulid':4 'aim':31 'contain':17 'current':42 'depend':38 'extern':37 'id':57 'identifi':27,54 'implement':3,20,35 'last':48 'lexicograph':25 'librari':9 'lightweight':34 'mainten':44 'march':51 'minim':14 'mode':45 'project':40 'provid':12 'py':8 'python':2,18 'releas':49 'self':16 'self-contain':15 'sortabl':26,56 'specif':29 'ulid':1,7,28,53 'ulid-pi':6 'uniqu':24 'univers':23 'uuid':55 'version':10 'without':36","created_at":"2026-04-11T01:44:54.944849+00:00","updated_at":"2026-04-16T23:53:18.050503+00:00","problems":[{"fix":"Import the `new` function explicitly from `ulid.api` or use the `ULID()` constructor from the main `ulid` package.\n\n```python\n# Fix 1: Import new function directly\nfrom ulid.api import new\nulid_obj = new()\n\n# Fix 2: Use the ULID constructor\nfrom ulid import ULID\nulid_obj = ULID()\n```","cause":"The `new` function for creating ULIDs is part of the `ulid.api` submodule, not directly exposed at the top-level `ulid` package when doing a simple `import ulid`.","error":"AttributeError: module 'ulid' has no attribute 'new'"},{"fix":"To parse a ULID string into a `ULID` object, use the `ULID.from_str()` class method instead of the constructor.\n\n```python\nfrom ulid import ULID\n\n# Correct way to parse a ULID string\nulid_string = \"01ARZ3RCK538M5064X1J0YSBPK\"\nulid_obj = ULID.from_str(ulid_string)\nprint(ulid_obj)\n```","cause":"This error occurs when attempting to parse a ULID string by passing it directly to the `ULID` class constructor, which expects either no arguments or specific `timestamp` and `entropy` arguments, not a string for parsing.","error":"TypeError: ULID() takes 0 or 2 positional arguments but 1 was given"},{"fix":"Ensure the input string is a valid 26-character ULID string in Crockford Base32 encoding. Validate the source of the ULID string.\n\n```python\nfrom ulid import ULID\n\n# Correct: A valid ULID string\nvalid_ulid_string = \"01GS81E0F1T2Q3M4N5P6R7S8T9\"\nparsed_ulid = ULID.from_str(valid_ulid_string)\nprint(parsed_ulid)\n\n# Incorrect example (would raise the ValueError)\n# invalid_ulid_string = \"not-a-ulid\"\n# parsed_ulid = ULID.from_str(invalid_ulid_string)\n```","cause":"This error is raised when `ULID.from_str()` or `ulid.api.parse()` attempts to convert a string that does not conform to the ULID specification (e.g., incorrect length, invalid characters, or invalid Crockford base32 encoding).","error":"ValueError: Invalid ULID string."},{"fix":"Install the `ulid-py` package using pip.\n\n```bash\npip install ulid-py\n```\n\nAfter installation, you should be able to import the module:\n```python\nimport ulid\nfrom ulid import ULID\n```","cause":"The `ulid-py` library, or specifically the `ulid` package it provides, is not installed in your current Python environment.","error":"ModuleNotFoundError: No module named 'ulid'"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.1.0","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/ahawker/ulid","docs":null,"changelog":null,"pypi":"https://pypi.org/project/ulid-py/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}