{"id":1684,"library":"python-ulid","title":"python-ulid","description":"python-ulid is a Python library that provides Universally Unique Lexicographically Sortable Identifiers (ULIDs). ULIDs are designed to be compatible with UUIDs but offer better performance for database indexing due to their time-based sort order. The library is actively maintained with regular updates, currently at version 3.1.0, and often introduces new features and stricter validation.","status":"active","version":"3.1.0","language":"python","source_language":"en","source_url":"https://github.com/mdomke/python-ulid","tags":["ulid","uuid","identifier","lexicographical","sorting","pydantic"],"install":[{"cmd":"pip install python-ulid","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"wrong":"import ulid","symbol":"ulid","correct":"import ulid"}],"quickstart":{"code":"from ulid import ULID\nimport time\n\n# Generate a new ULID\nulid_obj = ULID()\nprint(f\"Generated ULID: {ulid_obj}\")\nprint(f\"As string: {str(ulid_obj)}\")\nprint(f\"As bytes: {bytes(ulid_obj)}\") # requires >=2.3.0\nprint(f\"Timestamp (float): {ulid_obj.timestamp()}\")\nprint(f\"Datetime: {ulid_obj.datetime()}\")\n\n# Generate multiple ULIDs quickly to demonstrate monotonicity (requires 3.1.0+)\nprint(\"\\nMonotonicity check (same millisecond - may not trigger in all environments):\")\n# Simulate a very fast loop within a single millisecond\nulids_in_ms = []\nfor _ in range(5):\n    ulids_in_ms.append(ULID())\n    # Introduce a tiny delay if needed to help simulate\n    # pass # time.sleep(0.000001)\n\nfor u in ulids_in_ms:\n    print(f\"  {u}\")\n\n# Note: Asserting strict inequality `ulids_in_ms[i] < ulids_in_ms[i+1]` is generally true\n# due to monotonicity, but for simplicity, we just print here.\n# The library ensures ULIDs are unique and sorted within the same millisecond.\n\n# Parse a ULID from a string (ULID.parse() introduced in 3.0.0)\nulid_str = \"01HASJFZZ862S826DA2NJK4WMT\" # Example ULID\nparsed_ulid = ULID.parse(ulid_str)\nprint(f\"\\nParsed ULID: {parsed_ulid}\")\nprint(f\"Parsed ULID equals original string: {str(parsed_ulid) == ulid_str}\")\n\n# Convert to UUID (ULID.to_uuid4() introduced in 2.1.0)\nuuid_obj = ulid_obj.to_uuid4()\nprint(f\"Converted to UUID: {uuid_obj}\")","lang":"python","description":"This quickstart demonstrates how to generate ULIDs, convert them to string and bytes, parse them from strings, and shows the monotonicity feature introduced in 3.1.0 for sub-millisecond generation. It also includes conversion to UUIDs."},"warnings":[{"fix":"Update exception handling for `ULID` constructor calls. Ensure correct types are passed to the constructor.","message":"Calling the `ULID` constructor with an invalid type argument will now raise a `TypeError` instead of a `ValueError`.","severity":"breaking","affected_versions":"<3.0.0"},{"fix":"Ensure all input strings for ULID parsing strictly adhere to the ULID specification (Base32 alphabet, valid timestamp range). Implement robust error handling for parsing operations, particularly around `ULID.parse()` or `ULID.from_str()`.","message":"Parsing ULIDs from string or other inputs (`ULID.from_str`, `ULID.parse`) has become significantly stricter across versions 2.6.0, 2.7.0, and 3.0.0. Inputs that were previously accepted or silently coerced might now raise `ValueError` or `TypeError` due to invalid characters, out-of-range timestamps, or incorrect types.","severity":"breaking","affected_versions":"<2.6.0"},{"fix":"Be aware of this behavior if your application relies on entirely independent random components even for sub-millisecond generation. For most use cases, this improves lexicographical sortability and is the desired behavior.","message":"As of version 3.1.0, ULID generation within the same millisecond ensures monotonic sort order by incrementing the randomness component. While spec-compliant, this means the randomness component is not entirely 'random' when multiple ULIDs are generated in rapid succession within the same millisecond.","severity":"gotcha","affected_versions":"<3.1.0"},{"fix":"Upgrade `python-ulid` to version 2.3.0 or newer for full Pydantic v2 compatibility and improved JSON schema generation.","message":"Pydantic v2 protocol support for direct type annotation was introduced in version 2.3.0. If you are using `python-ulid` with Pydantic v2 and a version prior to 2.3.0, you might encounter issues with serialization or validation.","severity":"gotcha","affected_versions":"<2.3.0"}],"env_vars":null,"search_vec":"'3.1.0':53 'activ':45 'base':39 'better':29 'compat':24 'current':50 'databas':32 'design':21 'due':34 'featur':58 'identifi':17,64 'index':33 'introduc':56 'lexicograph':15,65 'librari':10,43 'maintain':46 'new':57 'offer':28 'often':55 'order':41 'perform':30 'provid':12 'pydant':67 'python':2,5,9 'python-ulid':1,4 'regular':48 'sort':40,66 'sortabl':16 'stricter':60 'time':38 'time-bas':37 'ulid':3,6,18,19,62 'uniqu':14 'univers':13 'updat':49 'uuid':26,63 'valid':61 'version':52","created_at":"2026-04-09T03:58:41.841152+00:00","updated_at":"2026-04-16T20:30:23.948536+00:00","problems":{"verify_error":"Traceback (most recent call last):\n  File \"<string>\", line 1, in <module>\n  File \"/tmp/tmp14o7mltr/venv/lib/python3.12/site-packages/ulid/__init__.py\", line 16, in <module>\n    from typing_extensions import Self\nModuleNotFoundError: No module named 'typing_extensions'"},"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"4.0.1","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/mdomke/python-ulid","docs":"https://python-ulid.readthedocs.io","changelog":"https://python-ulid.readthedocs.io/en/latest/changelog.html","pypi":"https://pypi.org/project/python-ulid/","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-07-03","last_verified":"2026-08-27","next_check":"2026-07-10","install_tag":null}}