A professional, extensible search algorithm framework for discrete spaces (graphs and grids). Implements A* with pluggable heuristics.
Project description
search-library
A professional, extensible search algorithm framework for discrete spaces (graphs and 2D grids).
Features
- A* Search Algorithm — optimal pathfinding with
f(n) = g(n) + h(n) - Graph support — weighted directed/undirected graphs with adjacency lists
- Grid support — 2D pathfinding with obstacles, variable costs, 4/8-directional movement
- Pluggable heuristics — Manhattan, Euclidean, or bring your own
- Extensible architecture — designed for adding BFS, DFS, Dijkstra without modifying base code
- Strict typing — full
mypy --strictcompliance with Generics and Protocols - Zero runtime dependencies — pure Python standard library only
Installation
pip install search-library
Or with uv:
uv add search-library
Quick Start
Graph Search
from search_library import Graph, AStarSearch
# Create an undirected weighted graph
graph = Graph[str](directed=False)
graph.add_edge("A", "B", 1.0)
graph.add_edge("B", "C", 2.0)
graph.add_edge("A", "C", 5.0)
# Solve with A*
problem = graph.to_search_problem("A", "C")
solver = AStarSearch(problem)
result = solver.search()
print(result.path) # ['A', 'B', 'C']
print(result.total_cost) # 3.0
print(result.nodes_explored) # 3
Grid Pathfinding (Maze)
from search_library import Grid, AStarSearch
from search_library.grid import GridSearchProblem
# 0 = walkable, 1 = obstacle
matrix = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 1, 0],
[0, 1, 0, 0, 0],
[0, 0, 0, 0, 0],
]
grid = Grid.from_matrix(matrix)
problem = GridSearchProblem(grid, start=(0, 0), goal=(4, 4))
solver = AStarSearch(problem)
result = solver.search()
print(result.success) # True
print(result.total_cost) # 8.0
print(result.nodes_explored) # Number of states explored
Custom Heuristic
from search_library.heuristics.base import Heuristic
class ChebyshevHeuristic(Heuristic[tuple[int, int]]):
"""Chebyshev distance — useful for 8-directional grids."""
def estimate(self, state: tuple[int, int], goal: tuple[int, int]) -> float:
return float(max(abs(state[0] - goal[0]), abs(state[1] - goal[1])))
Custom Search Problem
from search_library.core.problem import SearchProblem
from search_library.algorithms.astar import AStarSearch
class EightPuzzle(SearchProblem[tuple[int, ...]]):
"""Example: define any discrete search problem."""
def initial_state(self) -> tuple[int, ...]:
return (1, 2, 3, 4, 0, 5, 6, 7, 8)
def is_goal(self, state: tuple[int, ...]) -> bool:
return state == (1, 2, 3, 4, 5, 6, 7, 8, 0)
def successors(self, state: tuple[int, ...]) -> list[tuple[tuple[int, ...], float]]:
# Return list of (next_state, cost) tuples
...
Architecture
src/search_library/
├── core/ # Node, State (Protocol), SearchProblem (ABC), SearchResult
├── algorithms/ # A* implementation (extensible for BFS, DFS, Dijkstra)
├── heuristics/ # Heuristic ABC + Manhattan + Euclidean
├── graph/ # Graph + Edge + GraphSearchProblem adapter
├── grid/ # Grid + GridSearchProblem adapter (4/8 directions)
├── utils/ # Formatting helpers
└── exceptions/ # SearchError hierarchy
Design Principles
- SOLID — each class has a single responsibility; open for extension, closed for modification
- Strategy Pattern — heuristics are interchangeable at runtime
- Adapter Pattern — Graph and Grid adapt to the unified SearchProblem interface
- Generic Types — algorithms work with any hashable state type
Development
# Install all dependencies (including dev tools)
uv sync
# Run tests with coverage
uv run pytest
# Lint
uv run ruff check src/ tests/
# Format
uv run ruff format src/ tests/
# Type check (strict mode)
uv run mypy src/
# Build wheel + sdist
uv build
CI/CD
| Pipeline | Trigger | What it does |
|---|---|---|
| CI | push, PR | Ruff + MyPy + Pytest (matrix: 3.11, 3.12, 3.13, 3.14) |
| CD | push to main | CI + Semantic Release + PyPI publish |
Versioning follows Conventional Commits:
feat:→ minor version bumpfix:→ patch version bumpfeat!:/BREAKING CHANGE:→ major version bump
Roadmap
- A* Search Algorithm
- Manhattan & Euclidean heuristics
- Graph support (directed/undirected, weighted)
- Grid support (4/8 directions, obstacles)
- BFS (Breadth-First Search)
- DFS (Depth-First Search)
- Dijkstra's Algorithm
- Bidirectional Search
- Visualization utilities
License
MIT — free for academic and commercial use.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file search_library-0.2.0.tar.gz.
File metadata
- Download URL: search_library-0.2.0.tar.gz
- Upload date:
- Size: 19.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c0c5b9c08fac191de45790eaac5f63b14e1b4584a92f1efc52fd80ef4f2476c2
|
|
| MD5 |
2d3d03fa5dede1fafd96b589413a1bd7
|
|
| BLAKE2b-256 |
e78b21c32abe7f32ce582a17e1ed63d8319d96167e50e86966c8902e04bf2e55
|
Provenance
The following attestation bundles were made for search_library-0.2.0.tar.gz:
Publisher:
cd.yml on ahincho/search-library
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
search_library-0.2.0.tar.gz -
Subject digest:
c0c5b9c08fac191de45790eaac5f63b14e1b4584a92f1efc52fd80ef4f2476c2 - Sigstore transparency entry: 1889009839
- Sigstore integration time:
-
Permalink:
ahincho/search-library@39f8f111e276991c33fbf59a8577f528daf9a2bc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ahincho
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@39f8f111e276991c33fbf59a8577f528daf9a2bc -
Trigger Event:
push
-
Statement type:
File details
Details for the file search_library-0.2.0-py3-none-any.whl.
File metadata
- Download URL: search_library-0.2.0-py3-none-any.whl
- Upload date:
- Size: 20.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1719481251b277e06a9d19eff1a9df86b40088612ff6f616a37a6524cd34392a
|
|
| MD5 |
68f578623e03e1546d7fba490308b19d
|
|
| BLAKE2b-256 |
d43ee798bb75fd28e083e5f0899db0f50b201c4ddc6cfa123d59cb2a26fc0dd4
|
Provenance
The following attestation bundles were made for search_library-0.2.0-py3-none-any.whl:
Publisher:
cd.yml on ahincho/search-library
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
search_library-0.2.0-py3-none-any.whl -
Subject digest:
1719481251b277e06a9d19eff1a9df86b40088612ff6f616a37a6524cd34392a - Sigstore transparency entry: 1889010234
- Sigstore integration time:
-
Permalink:
ahincho/search-library@39f8f111e276991c33fbf59a8577f528daf9a2bc -
Branch / Tag:
refs/heads/main - Owner: https://github.com/ahincho
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
cd.yml@39f8f111e276991c33fbf59a8577f528daf9a2bc -
Trigger Event:
push
-
Statement type: