# Route Organization Tool

A tool for breaking up and organizing a Flask ows API 
`handlers.py` file, with formatting and linting 
capabilities.

## Prerequisites

- Python 3.x
- [Poetry](https://python-poetry.org/) (Python dependency management)
- [ruff](https://github.com/astral-sh/ruff) (Python linter and formatter)
- [astor](https://pypi.org/project/astor/) (for parsing 
Python code)
- [prettytable](https://pypi.org/project/prettytable/) 
(for listing routes)

## Installation

1. Install Poetry if you haven't already:
   ```bash
   curl -sSL https://install.python-poetry.org | python3 -
   ```

2. Install project dependencies using Poetry:
   ```bash
   poetry install
   ```

## Service Setup

1. Choose the Flask based ows service you want to organize (e.g., `ows-account`, `ows-track`)
2. Create a similar structure in this project:
   - If organizing `ows-account`, create:
     ```
     services/
     └── account
         └── handlers.py    # Copy the handlers.py file from ows-account here
     ```
   - If organizing `ows-permissions`, create:
     ```
     services/
     └── permissions
         └── handlers.py    # Copy the handlers.py file from ows-permissions here
     ```

The tool expects the service name (e.g., `account`, `permissions`) to match the directory name, and the file to organize should be named `handlers.py`.

## Route Configuration

Before running the tool, you'll need to create a configuration file that defines how your routes should be organized. This is the most important (and time-consuming) part of the process, but once set up, the tool will handle the reorganization automatically.

Create a config file for your service:
```
services/
└── account
    └── account.json    # e.g., services/account/account.json, services/permissions/permissions.json
```

The config file uses this structure:
```json
{
  "categories": {
    "category_name": {
      "group": "Group Name",
      "patterns": [
        "route_pattern1",
        "route_pattern2"
      ]
    }
  }
}
```

Routes can be matched using either:
- Direct path matching (e.g., `"/health"`)
- Regular expressions (e.g., `"^/vendor/<[\\w:]+>/suppliers$"`)

Example patterns:
```json
{
  "categories": {
    "health": {
      "group": "Health",
      "patterns": [
        "config.HEALTH_CHECK",     // Direct match
        "^/health$"               // Regex match
      ]
    },
    "vendor_core": {
      "group": "Vendor",
      "patterns": [
        "^/vendor$",
        "^/vendor/<[\\w:]+>$",    // Matches dynamic routes like /vendor/123
        "^/v2/vendors$"
      ]
    }
  }
}
```

Routes are matched in the order they appear in the config file. Include a catch-all category at the end (using `".*"`) to handle any unmatched routes.

See `services/account/account.json` for a complete example of how to structure your configuration file.

## Usage

To set the service name, you can either:
1. Update the SERVICE_NAME in the Makefile:
   ```makefile
   SERVICE_NAME := your_service_name
   ```
   and run the command:
   ```bash
    make organize
   ```
2. Or override it when running make commands:
   ```bash
   make organize SERVICE_NAME=your_service_name
   make compare SERVICE_NAME=your_service_name
   ```

This command will:
1. Run the route organizer script (`route_organizer.py`)
2. The script will generate a new directory with the organized handlers.
2. Format the code in `services/<SERVICE_NAME>/handlers` using ruff
3. Run linting checks and apply automatic fixes where possible

### Additional Commands

- `make fmt`: Format and lint the code without reorganizing routes
- `make compare`: Compare routes between the old and new handlers
- `make list_old`: List routes from the old handlers file
- `make list_new`: List routes from the new handlers directory

## Project Structure

- `route_organizer.py`: Main script for organizing routes
- `route_lister.py`: Utility for listing and comparing routes
- `services`: Directory for service handlers and configuration files

## Applying Changes
In your service repository, replace the original `handlers.py` file with the newly organized one from this project.
You will need to update the `application.py` file to import the new handlers file.
```python
from account.handlers import *  # noqa
```
Exmaple PR https://github.com/theorchard/ows-account/pull/619