Metadata-Version: 2.3
Name: flights-nlp
Version: 0.1.2
Summary: Natural language flight search parser — extract structured flight data from freeform text
Author: Michael Stefano Rioli
Author-email: Michael Stefano Rioli <michaelpersonal67@gmail.com>
Requires-Dist: airportsdata>=20260315
Requires-Dist: click>=8.4.2
Requires-Dist: janome>=0.5.0
Requires-Dist: pydantic>=2.13.4
Requires-Dist: spacy>=3.8.13
Requires-Python: >=3.10
Description-Content-Type: text/markdown

# flights-nlp ✈️

A robust, Django-friendly natural language flight search query parser for English and Japanese. It translates freeform text queries into structured parameters ready for flight search APIs (like Amadeus, Sabre, or Skyscanner).

## Features

- 🧠 **Hybrid Route Extraction**: Combines spaCy NLP models (`en_core_web_sm`/`ja_core_news_sm`) with geographic database lookups to reliably extract origin and destination cities/airports, resolving sequence ambiguities.
- 🇯🇵 **Spaceless Japanese Support**: Fully parses spaceless Japanese query layouts (e.g., `東京から札幌明日片道`).
- 📍 **Multi-Airport Cities (MAC)**: Resolves city and airport names (e.g., `羽田`, `成田`) to their IATA codes and ties them back to parent metropolitan codes (e.g., `TYO`).
- 🔍 **Airport Disambiguation**: Extracts parenthesized hints like `大阪(伊丹)` to target specific airports (e.g., `ITM`) instead of whole metropolitan areas.
- 📅 **Relative Dates & Durations**: Parses relative terms (`today`, `tomorrow`, `next week`, `来週の月曜日`), relative offsets (`3日後`, `2週間後`), and trip durations (`for a week`, `1週間`, `3日間`).
- 👥 **Passenger Parsing**: Normalizes numbers and counts for adults, children, and infants (e.g., `大人二人`, `2 adults 1 infant`).
- 🛡️ **Django Ready**: Fully optimized for web frameworks with startup model pre-loading (`preload_models`), custom exception classes, and standard Python logging hooks.

---

## Installation

Requires **Python 3.10+**. Install via `pip` or `uv`:

```bash
pip install flights-nlp
```

SpaCy language pipelines (`en_core_web_sm` / `ja_core_news_sm`) are downloaded automatically on first parse (or when you call `preload_models`). You can also install them manually:

```bash
python -m spacy download en_core_web_sm
python -m spacy download ja_core_news_sm
```

---

## Quick Start (Python API)

### Basic Parsing
```python
from datetime import date
from flights_nlp import parse

# Parse a query relative to a reference date
result = parse("Tokyo to Sapporo next week 3 adults", reference_date=date(2026, 7, 12))

print(result.origin)               # "Tokyo"
print(result.origin_iata)          # ["NRT", "HND"]
print(result.origin_city_code)     # "TYO"
print(result.destination)          # "Sapporo"
print(result.destination_iata)     # ["CTS", "OKD"]
print(result.departure_date)       # 2026-07-20
print(result.adults)               # 3
print(result.trip_type)            # "round_trip"
```

### Serializing to JSON
```python
print(result.to_json(indent=2))
```

### Django Startup Warmup (Model Pre-loading)
To prevent the initial web request from experiencing a ~2 second model loading latency, call `preload_models` inside your Django app's startup hook:

```python
# myapp/apps.py
from django.apps import AppConfig
from flights_nlp import preload_models

class MyAppConfig(AppConfig):
    name = "myapp"
    
    def ready(self):
        # Preload English and Japanese models
        preload_models(["en", "ja"])
```

### Custom Exception Handling
The library raises structured subclasses of `FlightsNLPError` (which inherits from `ValueError`):
- `RouteExtractionError`: Raised when origin/destination cannot be resolved.
- `DateResolutionError`: Raised when date formats are invalid.
- `PassengerParsingError`: Raised when passenger parameters are faulty.

---

## Command Line Interface (CLI)

The package installs a CLI tool `flights-nlp` to parse queries directly from the terminal.

### JSON Output (Default)
```bash
flights-nlp "Tokyo to Sapporo next week 3 adults"
```

### Table Output
```bash
flights-nlp "東京から札幌明日片道" --format table
```

**Output:**
```
┌────────────────┬─────────────────────────┐
│     Field      │          Value          │
├────────────────┼─────────────────────────┤
│ Origin         │ Tokyo [TYO] (NRT,HND)   │
│ Destination    │ Sapporo [SPK] (CTS,OKD) │
│ Departure Date │ 2026-07-13              │
│ Return Date    │ —                       │
│ Trip Type      │ one_way                 │
│ Adults         │ 1                       │
│ Children       │ 0                       │
│ Infants        │ 0                       │
└────────────────┴─────────────────────────┘
```

---

## Interactive Playground (Streamlit)

For developer testing, run the Streamlit visual debugger locally:

```bash
uv run streamlit run app.py
```

This starts a dashboard where you can type queries, inspect spaCy tokenization / entity tags, check JSON representations, and test various reference dates reactively.

---

## Running Tests

To run the full unit test suite:

```bash
pytest tests/
```
