Metadata-Version: 2.4
Name: country-resolver
Version: 0.1.0
Summary: Resolve ISO country codes from profile locations and biographies, fast and offline.
Author-email: Johaness <chyjohn777@gmail.com>
Classifier: Programming Language :: Python :: 3
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Requires-Python: >=3.8
Description-Content-Type: text/markdown
Requires-Dist: flashgeotext>=0.5.5
Requires-Dist: flashtext>=2.7
Requires-Dist: geonamescache>=3.0.1
Requires-Dist: geopy>=2.5.0
Requires-Dist: pycountry>=26.2.16
Requires-Dist: rapidfuzz>=3.14.5
Requires-Dist: spacy>=3.8.14
Provides-Extra: dev
Requires-Dist: pytest>=9.1.1; extra == "dev"

# country_resolver

> Fast, offline country resolution for social media profiles.

`country_resolver` is a Python package for inferring a user's country from social media profile information. It is designed for noisy, real-world profile data from platforms such as X (formerly Twitter), GitHub, Mastodon, Bluesky, and similar services.

The package consists of two complementary modules:

| Module                | Purpose                                                                                                      |
| --------------------- | ------------------------------------------------------------------------------------------------------------ |
| **Location Resolver** | Resolves the dedicated **location field** into an ISO 3166-1 alpha-2 country code.                           |
| **Bio Resolver**      | Infers a user's **current country of residence** from profile biographies using natural language processing. |

Together they provide a fast, explainable solution for country inference without relying on online geocoding services for most lookups.

---

# Why Two Resolvers?

Profile **location fields** and **biographies** require different approaches.

A location field is usually short and structured:

```
Lagos, Nigeria
🇳🇬
Naija
Berlin
```

A biography is free-form natural language:

```
Originally from Nigeria.
Based in Berlin.

AI Engineer • Living in Canada 🇨🇦

Building software.
Born in Ghana.
```

Trying to process both using the same algorithm either misses valid signals or produces unnecessary false positives.

`country_resolver` therefore provides two specialized resolvers that can be used independently or together.

---

# Features

* ⚡ Offline-first resolution
* 🌍 ISO 3166-1 alpha-2 country codes
* 🏙️ City-to-country lookup
* 🚩 Flag emoji support
* 🔤 Country aliases and abbreviations
* ✏️ Fuzzy matching for misspellings
* 🧠 spaCy-powered biography analysis
* 📊 Confidence scoring and evidence tracking
* 🔍 Explainable predictions
* 🧪 Comprehensive unit tests
* 🌐 Optional online geocoder fallback for address-like locations

---

# Installation

```bash
pip install country-resolver
```

For **Bio Resolver**, install the English spaCy model:

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

---

# Quick Start

## Location Resolver

```python
from country_resolver.location import LocationResolver

resolver = LocationResolver()

resolver.resolve("Lagos, Nigeria")
```

```python
'NG'
```

---

## Bio Resolver

```python
from country_resolver.bio import BioResolver

bio = BioResolver(location)

bio.resolve(
    "Originally from Nigeria. Based in Berlin."
)
```

```python
'DE'
```

---

# Which Resolver Should I Use?

| Your data              | Recommended module                         |
| ---------------------- | ------------------------------------------ |
| Profile location field | **Location Resolver**                      |
| Profile biography      | **Bio Resolver**                           |
| Both                   | Use both together for the highest accuracy |

---

# Example Inputs

| Input                                         | Module   | Output |
| --------------------------------------------- | -------- | ------ |
| `Nigeria`                                     | Location | `NG`   |
| `🇳🇬`                                        | Location | `NG`   |
| `Naija`                                       | Location | `NG`   |
| `Lagos`                                       | Location | `NG`   |
| `Caneda`                                      | Location | `CA`   |
| `Kora Nort`                                   | Location | `KP`   |
| `Earth`                                       | Location | `None` |
| `Based in Berlin.`                            | Bio      | `DE`   |
| `Living in Canada 🇨🇦`                       | Bio      | `CA`   |
| `Originally from Nigeria. Living in Germany.` | Bio      | `DE`   |

---

# Package Architecture

```
country_resolver/
│
├── location/
│   ├── resolver.py
│   ├── lookup.py
│   ├── normalize.py
│   ├── geocoder.py
│   └── ...
│
├── bio/
│   ├── resolver.py
│   ├── parser.py
│   ├── scoring.py
│   ├── extractors.py
│   └── ...
│
└── tests/
```

---

# Design Philosophy

### Offline First

The package performs all primary lookups locally.

Network requests are made only when the optional geocoder is enabled for address-like inputs.

---

### Deterministic

The same input always produces the same output.

---

### Conservative

Returning `None` is preferred over making an incorrect prediction.

---

### Explainable

Both resolvers expose the reasoning behind their predictions, making results suitable for debugging, analytics, and machine learning pipelines.

---

### Modular

Each resolver can be used independently, while sharing the same country resolution infrastructure.

---

# Documentation

Detailed module documentation is available in:

* `location/README.md`
* `bio/README.md`

These documents describe each resolver's internal workflow, API, limitations, examples, and implementation details.

---

# Testing

Run the full test suite with:

```bash
pytest
```

---

# Roadmap

Future development may include:

* Additional language support
* Improved contextual understanding
* Configurable scoring weights
* Expanded country aliases
* Combined multi-signal profile resolver
* Additional profile signal resolvers

---

# License

See the project root for licensing information.
