Skip to main content

A ClI for Neo4j

Project description

lom

A command-line tool for Neo4j with an interactive shell that can be used by people and by AI agents. Connect to a Neo4j database and the Neo4j Aura management API from a single binary — run Cypher queries, manage cloud instances, and perform administrative operations.


Installation

lom is a Go binary that has been wrapper as a Python package. You can use standard Python package tooling for installation, upgrades and removal

pip

pip install lom

pipx

pipx install lom

uv

uv tool install lom

uvx

uvx will install and execute lom. This means that you must include the commands you want to use with uvx

uvx -i lom YOUR_COMMANDS

Check the installation by running lom --help and you will see the help information.


Getting started

Run

# Run a subcommand directly
./bin/lom cypher "MATCH (n:Person) RETURN n.name LIMIT 5"
./bin/lom cloud instances list
./bin/lom admin show-databases
./bin/lom config list

# Point at a specific config file
./bin/lom --config-file ~/.lom/config.json cloud instances list

# Control output format
./bin/lom cypher --format json "MATCH (n) RETURN n LIMIT 10"
./bin/lom cloud instances list --format json
./bin/lom cloud instances list --format toon

Commands

All functionality is exposed as top-level subcommands. Running lom with no arguments prints help.

Subcommand Description
cypher [query] Execute a Cypher query against the connected database
cloud Manage Neo4j Aura cloud resources
admin Administrative operations against the connected database
config Manage CLI configuration

cypher

Executes a Cypher query against the connected database.

lom cypher "MATCH (n) RETURN n LIMIT 5"
lom cypher --param name=Alice "MATCH (n:Person {name:\$name}) RETURN n"
lom cypher --format json "MATCH (n) RETURN n"
lom cypher --format toon "MATCH (n)-[r]->(m) RETURN n,r,m"
lom cypher --limit 100 "MATCH (n) RETURN n"

Flags (placed before the query):

Flag Description
--param key=value Add a query parameter (repeatable). Values are auto-typed: int, float, bool, string.
--format table|toon|json|pretty-json|graph Override the output format for this query.
--limit N Override the auto-injected row limit.

Requires a Neo4j connection. If credentials are not configured, you are prompted to enter them on first use and they are saved to the config file.

cloud

Manages Neo4j Aura cloud resources.

Requires Aura credentials. If aura.client_id or aura.client_secret are not configured, you are prompted to enter them on first use.

lom cloud instances list
lom cloud instances ls                                                  # alias
lom cloud instances get <id>
lom cloud instances create name=<n> tenant=<id> [cloud=<p>] [region=<r>] [type=<t>] [version=<v>] [memory=<size>]
lom cloud instances update <id> [name=<new-name>] [memory=<size>]
lom cloud instances pause <id>
lom cloud instances resume <id>
lom cloud instances delete <id>
lom cloud instances rm <id>                                             # alias

lom cloud projects list
lom cloud projects get <id>

instances create requires name and tenant. All other fields fall back to aura.instance_defaults in the config. Set defaults to avoid repeating them on every invocation:

lom config set aura.instance_defaults.tenant_id abc-123
lom config set aura.instance_defaults.cloud_provider aws
lom cloud instances create name=my-db

Save your password. When instances create succeeds, the initial password is shown exactly once and cannot be recovered.

admin

Runs administrative commands against the connected database.

Requires a Neo4j connection. Same prerequisite as cypher.

lom admin show-users
lom admin show-databases

config

Manages CLI configuration. Changes made with set, delete, and reset are persisted to the config file immediately and take effect in the current session.

lom config list                                # show all keys, values, and descriptions
lom config list --format json
lom config set neo4j.uri bolt://myhost:7687
lom config set cypher.output_format json
lom config set aura.instance_defaults.region us-east-1
lom config delete neo4j.password              # reset a key to its default (prompts)
lom config reset                              # wipe config file, restore all defaults (prompts)

Configuration

Settings are resolved in this order, highest priority first:

CLI flags  >  environment variables  >  config file  >  defaults

Config file

The default config file path is ~/.lom/config.json. The directory and file are created automatically when credentials are first saved via an interactive prompt. Pass --config-file <path> to use a different location.

A full example:

{
  "log_level": "info",
  "log_format": "text",
  "log_output": "stderr",
  "log_file": "",
  "neo4j": {
    "uri": "bolt://localhost:7687",
    "username": "neo4j",
    "password": "secret",
    "database": "neo4j"
  },
  "aura": {
    "client_id": "your-client-id",
    "client_secret": "your-client-secret",
    "timeout_seconds": 30,
    "instance_defaults": {
      "tenant_id": "your-tenant-id",
      "cloud_provider": "gcp",
      "region": "europe-west1",
      "type": "enterprise-db",
      "version": "5",
      "memory": "8GB"
    }
  },
  "cypher": {
    "shell_limit": 25,
    "exec_limit": 100,
    "output_format": "table"
  },
  "telemetry": {
    "metrics": true
  }
}

Environment variables

All variables use the LOM_ prefix. Nested keys use underscores.

Variable Default Description
LOM_LOG_LEVEL info Log level: debug, info, warn, error
LOM_LOG_FORMAT text Log format: text, json
LOM_LOG_OUTPUT stderr Log destination: stderr, stdout, file
LOM_LOG_FILE (empty) Log file path (used when LOM_LOG_OUTPUT=file)
LOM_NEO4J_URI bolt://localhost:7687 Neo4j bolt URI
LOM_NEO4J_USERNAME neo4j Neo4j username
LOM_NEO4J_PASSWORD (empty) Neo4j password — prefer env over config file
LOM_NEO4J_DATABASE neo4j Neo4j database name
LOM_AURA_CLIENT_ID (empty) Aura API client ID
LOM_AURA_CLIENT_SECRET (empty) Aura API client secret — prefer env over config file
LOM_AURA_TIMEOUT_SECONDS 30 Aura API request timeout
LOM_AURA_INSTANCE_DEFAULTS_TENANT_ID (empty) Default tenant ID for new instances
LOM_AURA_INSTANCE_DEFAULTS_CLOUD_PROVIDER gcp Default cloud provider: aws, gcp, azure
LOM_AURA_INSTANCE_DEFAULTS_REGION europe-west1 Default region for new instances
LOM_AURA_INSTANCE_DEFAULTS_TYPE enterprise-db Default instance type
LOM_AURA_INSTANCE_DEFAULTS_VERSION 5 Default Neo4j version
LOM_AURA_INSTANCE_DEFAULTS_MEMORY 8GB Default instance memory
LOM_CYPHER_SHELL_LIMIT 25 Default LIMIT injected into cypher queries
LOM_CYPHER_EXEC_LIMIT 100 Default LIMIT in non-interactive mode
LOM_CYPHER_OUTPUT_FORMAT table Default output format: table, json, pretty-json, graph, toon
LOM_TELEMETRY_METRICS true Send anonymous usage metrics to Neo4j

Security note: LOM_NEO4J_PASSWORD and LOM_AURA_CLIENT_SECRET are intentionally not available as CLI flags. Passing secrets as flags exposes them in shell history and ps output.

CLI flags

--config-file string      Path to a JSON configuration file
--neo4j-uri string        Neo4j bolt URI
--neo4j-username string   Neo4j username
--neo4j-database string   Neo4j database name
--aura-client-id string   Aura API client ID
--aura-timeout int        Aura API timeout in seconds
--log-level string        Log level: debug, info, warn, error
--log-format string       Log format: text, json
--log-output string       Log destination: stderr, stdout, file
--log-file string         Log file path (when --log-output=file)
--format string           Output format: table, json, pretty-json, graph
--no-metrics              Disable anonymous usage metrics

--agent                   Enable agent mode (see Agent mode section)
--rw                      Permit write/mutating operations in agent mode
--request-id string       Correlation ID for agent-mode JSON responses
--timeout duration        Maximum command execution time (e.g. 30s)

Interactive credential prompts

When Neo4j or Aura credentials are missing, the CLI prompts for them interactively on first use and saves them to the config file. To skip prompts in automated or agent contexts, pre-populate credentials via environment variables or the config file.


Agent mode

The CLI is designed to be driven by AI agents, CI pipelines, and orchestration tools. Use --agent (or LOM_AGENT=true) to activate a safe, machine-readable operating mode.

Activating agent mode

# Via flag
lom --agent cloud instances list

# Via environment variable (recommended for pipelines — all invocations inherit it)
export LOM_AGENT=true
lom cloud instances list

What --agent does

Behaviour Human mode (default) Agent mode
Output format table json
Missing credentials Interactive prompt Structured JSON error on stdout, exit non-zero
Errors Written to stderr JSON envelope on stdout
Write operations Allowed with confirmation prompt Blocked unless --rw is also passed

The --rw flag

In agent mode, all operations that modify state are blocked by default. Pass --rw (or LOM_RW=true) to explicitly permit mutations:

# Blocked — returns READ_ONLY error
lom --agent cloud instances delete <id>

# Allowed — no prompt, executes immediately
lom --agent --rw cloud instances delete <id>

--rw governs all mutation categories uniformly:

Category Read operations Write operations (require --rw)
cypher Any read-only query Queries classified as write by Neo4j EXPLAIN
cloud instances list, get create, update, pause, resume, delete
cloud projects list, get (none currently)
admin show-users, show-databases (none currently)
config list set, delete, reset

Cypher write detection

For cypher commands in agent mode without --rw, the CLI automatically runs EXPLAIN on the query before execution. If Neo4j classifies the statement as a write (rw, w, or s), it is blocked:

# EXPLAIN detects a write — blocked
lom --agent cypher "CREATE (n:Person {name:'Alice'}) RETURN n"
# → {"status":"error","error":{"code":"WRITE_BLOCKED","message":"..."},...}

# Read query — EXPLAIN confirms safe, executes
lom --agent cypher "MATCH (n:Person) RETURN n.name LIMIT 10"

# EXPLAIN or PROFILE queries run as-is — no pre-check
lom --agent cypher "EXPLAIN MATCH (n) RETURN n"

With --rw, the EXPLAIN pre-check is skipped and queries execute directly.

Error envelope

All errors in agent mode are written to stdout as a JSON envelope so agents reading stdout get machine-readable failures:

{"status":"error","error":{"code":"READ_ONLY","message":"\"delete\" is a write operation; re-run with --rw to permit mutations"},"request_id":"a1b2c3","schema_version":"1"}

Error codes:

Code Meaning
READ_ONLY Write operation attempted without --rw
WRITE_BLOCKED Cypher write detected by EXPLAIN without --rw
MISSING_QUERY No cypher statement provided in agent mode
MISSING_CREDENTIALS Required credentials absent (no prompt in agent mode)
TIMEOUT Command exceeded --timeout duration
EXECUTION_ERROR Any other failure

Additional agent flags

--request-id string   Correlation ID included in JSON responses.
                      Auto-generated (UUID) if not supplied.
                      Env: LOM_REQUEST_ID

--timeout duration    Maximum time for a command to run (e.g. 30s, 2m).
                      Exit code 1 + TIMEOUT error on expiry.

Recommended orchestrator setup

export LOM_AGENT=true
export LOM_REQUEST_ID="pipeline-run-${RUN_ID}"  # inject your trace ID
export LOM_NEO4J_URI="bolt+s://your-instance.databases.neo4j.io"
export LOM_NEO4J_USERNAME="neo4j"
export LOM_NEO4J_PASSWORD="${NEO4J_PASSWORD}"

# Read operations work with no further flags
lom cypher "MATCH (n:Person) RETURN count(n)"

# Write operations require explicit --rw
lom --rw cypher "CREATE (n:Event {ts: datetime()}) RETURN n"

Contributing

Project structure

cmd/lom/
    main.go             Entry point — calls run() and os.Exit
    app.go              App struct, Cobra root command, startup wiring, flag definitions,
                        subcommand builders (buildCloudCommand, buildCypherCommand, etc.)

internal/
    config/             Config structs, Viper loader, Overrides, SaveConfiguration
    logger/             Logger interface and slog implementation
    analytics/          Mixpanel analytics service
    presentation/       Output formatters (text, JSON, pretty-JSON, table, graph)
    repository/         GraphRepository interface and Neo4j driver implementation
    service/
        interfaces.go       CypherService, CloudService, AdminService interfaces
        cypher_service.go
        cloud_service.go
        admin_service.go
        graph_service.go
    commands/           Category builders (pure wiring — no business logic)
        cypher.go
        cloud.go
        admin.go
        config.go           config list/set/delete/reset category
        prerequisites.go    Neo4jPrerequisite, AuraPrerequisite, interactive variants
    dispatch/           Command routing primitives
        dispatch.go         Registry interface, CommandHandler type, Context struct
        category.go         Category and Command types — Dispatch, Find, SetPrerequisite

The dependency direction is strict:

cmd  →  commands  →  service  →  repository
cmd  →  dispatch
commands  →  dispatch   (for Category / Command / Context types)

No package imports its own parent. dispatch does not import commands or service.


Adding a command

A command sits inside an existing category or sub-category. It takes positional arguments and returns a formatted string.

Example: adding admin show-indexes to the admin category

Open internal/commands/admin.go and chain another AddCommand call:

func BuildAdminCategory(svc service.AdminService) *dispatch.Category {
    return dispatch.NewCategory("admin", "Administrative operations...").
        AddCommand(&dispatch.Command{
            Name:        "show-users",
            // ... existing command ...
        }).
        AddCommand(&dispatch.Command{
            Name:        "show-indexes",
            Aliases:     []string{"idx"},
            Usage:       "show-indexes",
            Description: "List all indexes in the current database",
            Handler: func(args []string, ctx dispatch.Context) (string, error) {
                return svc.ShowIndexes(ctx.Context)
            },
        })
}

Aliases are registered automatically in dispatch and appear in parentheses in --help output:

lom admin show-indexes
lom admin idx           # same command

Example: adding a command to a sub-category

To add cloud instances clone <id>, open internal/commands/cloud.go and chain another AddCommand in buildInstancesCategory:

func buildInstancesCategory(svc service.CloudService) *dispatch.Category {
    return dispatch.NewCategory("instances", "Manage Aura DB instances").
        AddCommand(instanceListCmd(svc)).
        // ...existing commands...
        AddCommand(&dispatch.Command{
            Name:        "clone",
            Usage:       "clone <id>",
            Description: "Clone an existing instance",
            Handler: func(args []string, ctx dispatch.Context) (string, error) {
                if len(args) == 0 {
                    return "", fmt.Errorf("usage: cloud instances clone <id>")
                }
                return fmt.Sprintf("Instance %s cloned.", args[0]), nil
            },
        })
}

Adding a category

To add a new top-level category (e.g. gds for Graph Data Science):

Step 1 — Add a service interface

In internal/service/interfaces.go:

type GDSService interface {
    ListAlgorithms(ctx context.Context) ([]string, error)
    RunPageRank(ctx context.Context, graphName string) (string, error)
}

Step 2 — Implement the service

Create internal/service/gds_service.go:

package service

type GDSServiceImpl struct {
    repo repository.GraphRepository
}

func NewGDSService(repo repository.GraphRepository) GDSService {
    return &GDSServiceImpl{repo: repo}
}

func (s *GDSServiceImpl) ListAlgorithms(ctx context.Context) ([]string, error) {
    // CALL gds.list()
    return nil, nil
}

Step 3 — Build the category

Create internal/commands/gds.go:

package commands

import (
    "strings"

    "github.com/cli/go-cli-tool/internal/dispatch"
    "github.com/cli/go-cli-tool/internal/service"
)

func BuildGDSCategory(svc service.GDSService) *dispatch.Category {
    return dispatch.NewCategory("gds", "Graph Data Science operations").
        AddCommand(&dispatch.Command{
            Name:        "list-algorithms",
            Usage:       "list-algorithms",
            Description: "List available GDS algorithms",
            Handler: func(args []string, ctx dispatch.Context) (string, error) {
                algos, err := svc.ListAlgorithms(ctx.Context)
                if err != nil {
                    return "", err
                }
                return strings.Join(algos, "\n"), nil
            },
        })
}

Step 4 — Wire it into App

In cmd/lom/app.go, add the service field, construct it in newApp, and register the category and its Cobra subcommand:

// In newApp(), after repo is created:
gdsSvc := service.NewGDSService(repo)

// In buildCategories():
"gds": commands.BuildGDSCategory(a.gdsSvc).
    SetPrerequisite(commands.InteractiveNeo4jPrerequisite(&a.cfg.Neo4j, a.cfg, configPath)),

// In buildRootCommand():
rootCmd.AddCommand(buildGDSCommand())

func buildGDSCommand() *cobra.Command {
    return &cobra.Command{
        Use:   "gds",
        Short: "Graph Data Science operations",
        RunE:  runCategory("gds"),
        SilenceUsage:  true,
        SilenceErrors: true,
    }
}

Use InteractiveNeo4jPrerequisite for database-connected categories and InteractiveAuraPrerequisite for Aura API categories. Add new prerequisite factories to internal/commands/prerequisites.go if neither fits.

The category is then available as a direct subcommand:

lom gds list-algorithms
lom gds --help

Code conventions

Service pattern — business logic lives in internal/service. Command handlers in internal/commands call services; they contain no logic of their own beyond argument validation and output formatting.

Interfaces before implementations — new behaviour starts with an interface in internal/service/interfaces.go. This keeps the command layer decoupled from concrete implementations and makes testing straightforward.

Prerequisite checks belong in prerequisites.go — if a category requires an external dependency (database connection, API credentials), declare it with SetPrerequisite in buildCategories. Write the factory function in internal/commands/prerequisites.go so it is independently testable. The check runs before every real dispatch, but bare category invocations (e.g. lom cypher --help) always show help regardless.

Command aliases are first-class — add short-form names via the Aliases []string field on dispatch.Command. Aliases are resolved in dispatch and shown in --help output. Register the canonical name as Name; aliases are supplementary.

Secrets stay out of flags — passwords and API secrets must not be CLI flags. Accept them only via environment variables, the config file, or interactive prompts.

Errors are the caller's responsibility — return fmt.Errorf("context: %w", err) and let the caller handle it. Don't call os.Exit or log.Fatal from inside a service or command handler.

No imports up the stackdispatch does not import commands or service. commands does not import tools. Keep the dependency graph acyclic and flowing in one direction toward cmd.

Declare MutationMode on every command and tool — every dispatch.Command and tool.Tool must declare its MutationMode. Use ModeRead (default) for read-only operations, ModeWrite for operations that always modify state, and ModeConditional for operations where mutability depends on runtime input (Cypher queries). The dispatcher enforces the read-only contract in agent mode automatically, so individual handlers do not need to check ctx.AgentMode for blocking. Handlers should check ctx.AgentMode only to suppress interactive prompts (e.g. confirmation dialogs).


CI & Releases

One GitHub Actions workflow manages the release process.

Workflows

Workflow Trigger What it does
Release Push of a vX.Y.Z tag Gates on tests, builds cross-platform binaries via GoReleaser, extracts the changelog section, creates a GitHub Release

Making a release

Releases follow a four-step process. changie collects unreleased fragment files and determines the correct semver bump automatically from the change kinds (Added → minor, Fixed/Security → patch, Changed/Removed → major).

1. Batch and merge the changelog

changie batch   # collects .changes/unreleased/*.yaml → .changes/vX.Y.Z.md
changie merge   # folds that file into CHANGELOG.md

2. Commit and tag

git add CHANGELOG.md .changes/
git commit -m "chore: release v0.2.0"
git tag v0.2.0
git push origin main --tags

Adding a changelog entry

Every PR that changes Go source files needs a changie fragment. Run:

changie new

Choose a kind and write a one-line summary, then commit the generated .yaml file alongside your code changes.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

lom-3.3.0-py3-none-win_arm64.whl (19.4 MB view details)

Uploaded Python 3Windows ARM64

lom-3.3.0-py3-none-win_amd64.whl (20.6 MB view details)

Uploaded Python 3Windows x86-64

lom-3.3.0-py3-none-manylinux_2_17_x86_64.whl (20.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ x86-64

lom-3.3.0-py3-none-manylinux_2_17_aarch64.whl (19.2 MB view details)

Uploaded Python 3manylinux: glibc 2.17+ ARM64

lom-3.3.0-py3-none-macosx_11_0_arm64.whl (19.4 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

lom-3.3.0-py3-none-macosx_10_9_x86_64.whl (20.3 MB view details)

Uploaded Python 3macOS 10.9+ x86-64

File details

Details for the file lom-3.3.0-py3-none-win_arm64.whl.

File metadata

  • Download URL: lom-3.3.0-py3-none-win_arm64.whl
  • Upload date:
  • Size: 19.4 MB
  • Tags: Python 3, Windows ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for lom-3.3.0-py3-none-win_arm64.whl
Algorithm Hash digest
SHA256 8dd722fe0a5804624a99db8fede5452d2a520a4c6dbc610f71b42cb1517e2c83
MD5 40768cd5ce51119fca718e4bc047fc5f
BLAKE2b-256 45990823d3ac26fbe4ef303e14f2f8f4100df79116f70ada9ac2be0eba548fb9

See more details on using hashes here.

File details

Details for the file lom-3.3.0-py3-none-win_amd64.whl.

File metadata

  • Download URL: lom-3.3.0-py3-none-win_amd64.whl
  • Upload date:
  • Size: 20.6 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for lom-3.3.0-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 54cee911c538da4029154e96ad7a9e4e57876f978874e534c35113aae6eee818
MD5 0ddbd9d4dcb280cdfc7bfa4e7966b744
BLAKE2b-256 89c6d5d6f7feb0b9637bece263aaa2162fce1db287e6eb59f8bf3c2ad77f9d73

See more details on using hashes here.

File details

Details for the file lom-3.3.0-py3-none-manylinux_2_17_x86_64.whl.

File metadata

  • Download URL: lom-3.3.0-py3-none-manylinux_2_17_x86_64.whl
  • Upload date:
  • Size: 20.2 MB
  • Tags: Python 3, manylinux: glibc 2.17+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for lom-3.3.0-py3-none-manylinux_2_17_x86_64.whl
Algorithm Hash digest
SHA256 441b01d26e4b67d2e61ebb8aeb5891aaa9f599d894c61f64ee4cd2420cdf53d3
MD5 ef5040c42566cb2126afda5d9eece41d
BLAKE2b-256 cc199ad0c310c6bb2075e0fac17f70370b9d71294e4868b4c5b0d2037c872882

See more details on using hashes here.

File details

Details for the file lom-3.3.0-py3-none-manylinux_2_17_aarch64.whl.

File metadata

  • Download URL: lom-3.3.0-py3-none-manylinux_2_17_aarch64.whl
  • Upload date:
  • Size: 19.2 MB
  • Tags: Python 3, manylinux: glibc 2.17+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for lom-3.3.0-py3-none-manylinux_2_17_aarch64.whl
Algorithm Hash digest
SHA256 3b04c3ba952d36603dbde31cca4c42249437cb64c4db07db34ac1eb9eecd8599
MD5 cafc79d20bc51af022b8cee262396e3c
BLAKE2b-256 1b25d7f449ef85c814bbe6fc7ef51f12bb8ae13d084eec59d31d277c4c856b31

See more details on using hashes here.

File details

Details for the file lom-3.3.0-py3-none-macosx_11_0_arm64.whl.

File metadata

  • Download URL: lom-3.3.0-py3-none-macosx_11_0_arm64.whl
  • Upload date:
  • Size: 19.4 MB
  • Tags: Python 3, macOS 11.0+ ARM64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for lom-3.3.0-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 b5487f6c67837c4e02bca99eb9eadea036ab85c07dacb40c600105d9a0b6c126
MD5 5ee1ff762da33258a17a91d10b8645b5
BLAKE2b-256 145d1c2b00470e671231ccd312569ddb1f217d95a827b6a6c74a46709f94fb5b

See more details on using hashes here.

File details

Details for the file lom-3.3.0-py3-none-macosx_10_9_x86_64.whl.

File metadata

  • Download URL: lom-3.3.0-py3-none-macosx_10_9_x86_64.whl
  • Upload date:
  • Size: 20.3 MB
  • Tags: Python 3, macOS 10.9+ x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.13

File hashes

Hashes for lom-3.3.0-py3-none-macosx_10_9_x86_64.whl
Algorithm Hash digest
SHA256 dea6b215d9d31241f15fdf19f4736a6c52604532b2b6f6c19fb00c6914510fc8
MD5 e242fcd8d69dc76d4b182c59d3a6f132
BLAKE2b-256 04285d9b774bb1475a08fb503cfa2d5448b025748b37785306724b598ce180ea

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page