Skip to content

Commit 2e25efe

Browse files
author
github-actions
committed
docs: refresh README and add release notes
1 parent 58020ae commit 2e25efe

File tree

2 files changed

+72
-182
lines changed

2 files changed

+72
-182
lines changed

README.md

Lines changed: 42 additions & 182 deletions
Original file line numberDiff line numberDiff line change
@@ -4,102 +4,65 @@
44
[![Ruff](https://github.com/Abstract-Data/RyanData-Address-Utils/actions/workflows/lint.yml/badge.svg)](https://github.com/Abstract-Data/RyanData-Address-Utils/actions/workflows/lint.yml)
55
[![MyPy](https://github.com/Abstract-Data/RyanData-Address-Utils/actions/workflows/typecheck.yml/badge.svg)](https://github.com/Abstract-Data/RyanData-Address-Utils/actions/workflows/typecheck.yml)
66
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
7+
[![uv](https://img.shields.io/badge/packaging-uv-9055ff.svg)](https://github.com/astral-sh/uv)
78
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
89

9-
A Python address parser built for Ryan Data that uses `usaddress` to parse US addresses into structured Pydantic models with ZIP code and state validation.
10+
Parse and validate US addresses with Pydantic models, ZIP/state validation, pandas integration, and semantic-release powered CI.
1011

11-
## Installation
12+
## Highlights
1213

13-
### Using pip
14+
- Structured parsing of US addresses into 26 components with Pydantic models
15+
- ZIP and state validation backed by authoritative datasets
16+
- Pandas-friendly parsing for batch workloads
17+
- Custom errors (`RyanDataAddressError`, `RyanDataValidationError`) with package context
18+
- Builder API for programmatic address construction
19+
- Semantic-release CI for automated tagging and releases
1420

15-
```bash
16-
pip install git+https://github.com/Abstract-Data/RyanData-Address-Utils.git
17-
```
18-
19-
With pandas support:
20-
21-
```bash
22-
pip install "ryandata-address-utils[pandas] @ git+https://github.com/Abstract-Data/RyanData-Address-Utils.git"
23-
```
24-
25-
### Using uv
21+
## Install
2622

23+
### uv (recommended)
2724
```bash
2825
uv add git+https://github.com/Abstract-Data/RyanData-Address-Utils.git
29-
```
30-
31-
With pandas support:
32-
33-
```bash
26+
# with pandas extras
3427
uv add "ryandata-address-utils[pandas] @ git+https://github.com/Abstract-Data/RyanData-Address-Utils.git"
3528
```
3629

37-
Or from local directory:
38-
30+
### pip
3931
```bash
40-
git clone https://github.com/Abstract-Data/RyanData-Address-Utils.git
41-
cd RyanData-Address-Utils
42-
uv sync
32+
pip install git+https://github.com/Abstract-Data/RyanData-Address-Utils.git
33+
pip install "ryandata-address-utils[pandas] @ git+https://github.com/Abstract-Data/RyanData-Address-Utils.git"
4334
```
4435

45-
## Quick Start
36+
## Quick start
4637

4738
```python
4839
from ryandata_address_utils import AddressService, parse
4940

50-
# Simple parsing
5141
result = parse("123 Main St, Austin TX 78749")
52-
5342
if result.is_valid:
54-
print(result.address.StreetName) # "Main"
55-
print(result.address.ZipCode) # "78749"
56-
print(result.to_dict()) # All fields as dict
43+
print(result.address.ZipCode) # "78749"
44+
print(result.to_dict()) # full address dict
5745
else:
58-
print(result.validation.errors)
46+
print(result.validation.errors) # custom errors with context
5947

60-
# Or use the full service
6148
service = AddressService()
62-
result = service.parse("456 Oak Ave, Dallas TX 75201")
49+
service.parse("456 Oak Ave, Dallas TX 75201")
6350
```
6451

65-
## Key Features
66-
67-
- **Parse US addresses** into 26 structured components
68-
- **Validate ZIP codes** against real US ZIP code database (~33,000 ZIPs)
69-
- **Validate states** - abbreviations and full names
70-
- **Pandas integration** for batch processing
71-
- **Extensible architecture** - swap parsers, data sources, validators
72-
- **Builder pattern** for programmatic address constructionYes
73-
74-
## Pandas Integration
52+
## Pandas integration
7553

7654
```python
7755
import pandas as pd
7856
from ryandata_address_utils import AddressService
7957

80-
df = pd.DataFrame({
81-
"address": [
82-
"123 Main St, Austin TX 78749",
83-
"456 Oak Ave, Dallas TX 75201",
84-
]
85-
})
86-
58+
df = pd.DataFrame({"address": ["123 Main St, Austin TX 78749", "456 Oak Ave, Dallas TX 75201"]})
8759
service = AddressService()
88-
result = service.parse_dataframe(df, "address") # <-- This is where your named address column goes, and then it'll parse and add the split cols to the dataframe
89-
print(result[["AddressNumber", "StreetName", "ZipCode"]])
90-
```
9160

92-
### Options
93-
94-
```python
95-
# Skip validation (for non-US addresses)
96-
result = service.parse("123 Main St", validate=False)
97-
98-
# Add prefix to new columns
99-
result = service.parse_dataframe(df, "address", prefix="addr_")
61+
parsed = service.parse_dataframe(df, "address", prefix="addr_")
62+
print(parsed[["addr_AddressNumber", "addr_StreetName", "addr_ZipCode"]])
10063
```
10164

102-
## Build Addresses Programmatically
65+
## Programmatic build
10366

10467
```python
10568
from ryandata_address_utils import AddressBuilder
@@ -116,139 +79,36 @@ address = (
11679
)
11780
```
11881

119-
## API Reference
120-
121-
### AddressService (Main Interface)
122-
123-
```python
124-
from ryandata_address_utils import AddressService
125-
126-
service = AddressService()
127-
128-
# Parse single address
129-
result = service.parse("123 Main St, Austin TX 78749")
130-
result.is_valid # True if parsing and validation succeeded
131-
result.address # Address model
132-
result.validation # ValidationResult with any errors
133-
134-
# Parse batch
135-
results = service.parse_batch(["addr1", "addr2", "addr3"])
136-
137-
# Parse DataFrame
138-
df = service.parse_dataframe(df, "address_column")
139-
140-
# ZIP lookups
141-
info = service.lookup_zip("78749")
142-
city, state = service.get_city_state_from_zip("78749")
143-
```
144-
145-
### Address Model Fields
146-
147-
| Field | Description | Example |
148-
|-------|-------------|---------|
149-
| `AddressNumber` | Street number | "123" |
150-
| `StreetName` | Street name | "Main" |
151-
| `StreetNamePostType` | Street type | "St", "Ave" |
152-
| `StreetNamePreDirectional` | Direction before | "North" |
153-
| `StreetNamePostDirectional` | Direction after | "SE" |
154-
| `SubaddressType` | Unit type | "Apt", "Suite" |
155-
| `SubaddressIdentifier` | Unit number | "2B" |
156-
| `PlaceName` | City | "Austin" |
157-
| `StateName` | State (validated) | "TX" |
158-
| `ZipCode` | ZIP (validated) | "78749" |
159-
| `USPSBoxType` | PO Box type | "PO Box" |
160-
| `USPSBoxID` | PO Box number | "1234" |
161-
162-
### ZIP Code Utilities
163-
164-
```python
165-
from ryandata_address_utils import (
166-
get_city_state_from_zip,
167-
get_zip_info,
168-
is_valid_zip,
169-
is_valid_state,
170-
normalize_state,
171-
)
172-
173-
# Look up city/state from ZIP
174-
city, state = get_city_state_from_zip("78749") # ("Austin", "TX")
82+
## Workflow at a glance
17583

176-
# Get detailed ZIP info
177-
info = get_zip_info("78749")
178-
print(info.city, info.state_id, info.county_name)
179-
180-
# Validation
181-
is_valid_zip("78749") # True
182-
is_valid_state("Texas") # True
183-
normalize_state("Texas") # "TX"
84+
```mermaid
85+
flowchart LR
86+
parseStep[Parse] --> validateStep[Validate ZIP/State]
87+
validateStep --> testsStep[Tests & Lint]
88+
testsStep --> releaseStep[semantic-release]
89+
releaseStep --> githubRelease[GitHub Release + Artifacts]
18490
```
18591

186-
## Extensible Architecture
187-
188-
The package uses Protocols and Factories for extensibility:
189-
190-
```python
191-
from ryandata_address_utils import (
192-
AddressService,
193-
ParserFactory,
194-
DataSourceFactory,
195-
)
196-
197-
# Use custom data source
198-
custom_source = DataSourceFactory.create("csv", csv_path="/path/to/zips.csv")
199-
service = AddressService(data_source=custom_source)
200-
201-
# Register custom parser
202-
ParserFactory.register("custom", MyCustomParser)
203-
parser = ParserFactory.create("custom")
204-
```
92+
## APIs you get
20593

206-
## Development
94+
- `AddressService`: parse single, batch, DataFrame; look up ZIP/state; validate
95+
- `parse(...)`: convenience wrapper returning `ParseResult`
96+
- ZIP utilities: `get_city_state_from_zip`, `get_zip_info`, `is_valid_zip`, `is_valid_state`, `normalize_state`
97+
- Builder: `AddressBuilder` for programmatic address construction
20798

208-
### Using uv (Recommended)
99+
## Development (uv)
209100

210101
```bash
211102
git clone https://github.com/Abstract-Data/RyanData-Address-Utils.git
212103
cd RyanData-Address-Utils
213-
214-
# Install with dev dependencies
215104
uv sync
216-
217-
# Run tests
218105
uv run pytest
219-
220-
# Run linter
221106
uv run ruff check src/
222-
223-
# Run type checker
224107
uv run mypy src/
225-
226-
# Format code
227108
uv run ruff format src/
228109
```
229110

230-
### Using pip + Makefile
231-
232-
```bash
233-
git clone https://github.com/Abstract-Data/RyanData-Address-Utils.git
234-
cd RyanData-Address-Utils
235-
236-
# Install with dev dependencies
237-
make install-dev
238-
239-
# Run tests
240-
make test
241-
242-
# Run linter
243-
make lint
244-
245-
# Run type checker
246-
make typecheck
247-
248-
# Format code
249-
make format
250-
```
251-
252-
## License
253-
254-
MIT
111+
## Contributing and support
112+
- Issues: https://github.com/Abstract-Data/RyanData-Address-Utils/issues
113+
- Releases/notes: https://github.com/Abstract-Data/RyanData-Address-Utils/releases
114+
- License: MIT

release_notes.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Release Notes for v0.3.0
2+
3+
## Features
4+
- **Enhanced Error Handling**: Added `RyanDataAddressError` and `RyanDataValidationError` classes that inherit from Pydantic's error types while including package identification for better error tracing
5+
- **Automatic Address Formatting**: Implemented automatic Address1, Address2, and FullAddress property computation using Pydantic model validators
6+
- **Raw Input Preservation**: Added RawInput field to Address model to capture original input strings
7+
- **Automated Releases**: Reinstated GitHub Actions release workflow with semantic-release for automated versioning and releases
8+
9+
## Fixes
10+
- **Pandas Integration**: Fixed validation error handling in pandas integration methods when `errors='coerce'` is used
11+
- **Workflow Issues**: Resolved GitHub Actions workflow failures and cache problems
12+
- **Import Compatibility**: Cleaned up imports for Python 3.9+ compatibility
13+
- **Version Handling**: Made version reading more robust to prevent import errors
14+
- **Git Configuration**: Fixed release workflow git configuration issues
15+
16+
## Documentation
17+
- **UV Support**: Added comprehensive UV installation and development instructions
18+
- **Badge Updates**: Updated README badges to reference correct GitHub Actions workflows
19+
20+
## Refactoring
21+
- **Model Validators**: Replaced property-based address formatting with Pydantic model validators for better performance and consistency
22+
23+
## Chores
24+
- **Code Formatting**: Applied ruff formatting across entire codebase
25+
- **Dependency Updates**: Updated uv.lock and project dependencies
26+
- **CI/CD**: Configured semantic-release for automated releases
27+
28+
---
29+
30+
**Full Changelog**: https://github.com/Abstract-Data/RyanData-Address-Utils/compare/v0.2.0...v0.3.0

0 commit comments

Comments
 (0)