Clean URL handling made easy
Project description
urlops
Clean URL handling made easy.
Overview
urlops provides a simple, clean API for working with URLs. It offers immutable URL objects with intuitive operations that make URL manipulation feel natural.
Features
- Intuitive API - Natural operations like
/for path joining - Immutable design - All operations return new instances
- Multi-value query parameters - Proper handling of complex query strings
- Custom exceptions - Only uses urlops-specific exceptions, never built-in Python exceptions
- Simple and focused - Core functionality without unnecessary complexity
Installation
From PyPI (when available)
pip install urlops
From Source
# Clone the repository
git clone https://github.com/RVV-karma/urlops.git
cd urlops
# Install in development mode
pip install -e .
# Or install with development dependencies
pip install -e ".[dev]"
Requirements
- Python 3.8 or higher
- No external dependencies (pure Python implementation)
Development Setup
# Clone and setup
git clone https://github.com/RVV-karma/urlops.git
cd urlops
# Install development dependencies
make dev-install
# Run tests
make test
# Run linting and formatting
make lint
make format
Quick Start
from urlops import URL, parse, join
# Create a URL
url = URL("https://example.com/api/users?page=1&sort=name")
# Access components
print(url.scheme) # "https"
print(url.host) # "example.com"
print(url.port) # None
print(url.path) # URLPath("/api/users")
print(url.query) # QueryParams("page=1&sort=name")
print(url.fragment) # ""
# Path operations (intuitive syntax)
new_url = url / "123" / "profile"
print(new_url) # "https://example.com/api/users/123/profile"
# Query parameter manipulation
query = url.query
print(query.get("page")) # "1"
print(query.get_all("tag")) # [] (empty for non-existent keys)
# Immutable modification
new_url = url.with_host("api.example.com").with_port(8080)
print(new_url) # "https://api.example.com:8080/api/users?page=1&sort=name"
Detailed Examples
URL Creation and Parsing
from urlops import URL, parse
# Different ways to create URLs
url1 = URL("https://example.com/path")
url2 = parse("https://example.com/path") # Factory function
url3 = URL("//example.com/path") # Protocol-relative
url4 = URL("/relative/path") # Relative URL
# Check URL properties
print(url1.is_absolute()) # True
print(url4.is_absolute()) # False
print(url1.is_valid()) # True
Path Operations
from urlops import URL
url = URL("https://example.com/api/v1")
# Path joining with /
new_url = url / "users" / "123"
print(new_url) # "https://example.com/api/v1/users/123"
# Path properties
path = new_url.path
print(path.name) # "123"
print(path.stem) # "123" (no extension)
print(path.suffix) # "" (no extension)
print(path.parent) # URLPath("/api/v1/users")
# Path modification
new_path = path.with_name("profile.json")
print(new_path) # URLPath("/api/v1/users/profile.json")
# File-like operations
file_path = URL("https://example.com/docs/guide.pdf").path
print(file_path.stem) # "guide"
print(file_path.suffix) # ".pdf"
Query Parameter Handling
from urlops import URL
# Create URL with query parameters
url = URL("https://api.example.com/search?q=python&category=web&tag=api&tag=rest")
# Access query parameters
query = url.query
print(query.get("q")) # "python"
print(query.get("category")) # "web"
print(query.get_all("tag")) # ["api", "rest"]
print(query.keys()) # ["q", "category", "tag"]
print(len(query)) # 4 (total key-value pairs)
# Modify query parameters (immutable)
new_query = query.add("page", "2").set("q", "javascript")
print(new_query) # "q=javascript&category=web&tag=api&tag=rest&page=2"
# Remove parameters
clean_query = new_query.remove("tag")
print(clean_query) # "q=javascript&category=web&page=2"
# Builder pattern
final_query = query.with_(page="3", limit="10")
print(final_query) # "q=python&category=web&tag=api&tag=rest&page=3&limit=10"
URL Modification
from urlops import URL
base_url = URL("https://example.com/api")
# Modify different components
api_url = base_url.with_scheme("https").with_host("api.example.com").with_port(8080)
print(api_url) # "https://api.example.com:8080/api"
# Path operations
users_url = api_url / "users" / "123"
print(users_url) # "https://api.example.com:8080/api/users/123"
# Query and fragment
final_url = users_url.with_query("format=json").with_fragment("profile")
print(final_url) # "https://api.example.com:8080/api/users/123?format=json#profile"
Factory Functions
from urlops import parse, join
# Parse function
url = parse("https://example.com/api/v1")
# Join function for building URLs
base = parse("https://api.example.com")
api_url = join(base, "v1", "users", "123")
print(api_url) # "https://api.example.com/v1/users/123"
Error Handling
from urlops import URL, ParseError, ValidationError, TypeError
try:
# Invalid URL
url = URL("invalid://url")
except ValidationError as e:
print(f"Invalid URL: {e}")
try:
# Invalid port
url = URL("https://example.com:99999")
except ValidationError as e:
print(f"Invalid port: {e}")
try:
# Double slash in path
url = URL("https://example.com//invalid")
except ValidationError as e:
print(f"Invalid path: {e}")
try:
# Wrong type
url = URL(123)
except TypeError as e:
print(f"Type error: {e}")
Real-World Examples
from urlops import URL
# API endpoint construction
base_api = URL("https://api.github.com")
user_endpoint = base_api / "users" / "octocat"
repos_endpoint = user_endpoint / "repos"
# Add query parameters
search_url = repos_endpoint.with_query("type=public&sort=updated")
print(search_url) # "https://api.github.com/users/octocat/repos?type=public&sort=updated"
# CDN URL construction
cdn_base = URL("https://cdn.example.com")
asset_url = cdn_base / "images" / "logo.png"
print(asset_url) # "https://cdn.example.com/images/logo.png"
# Web scraping URL handling
scrape_url = URL("https://example.com/articles/2024/01/15")
article_id = scrape_url.path.name # "15"
year = scrape_url.path.parent.name # "2024"
Development Status
This project is currently in Stable (1.0.5). The core functionality is complete and ready for production use.
Contributing
Contributions are welcome! Please see our TODO.md for current development tasks.
Repository
This project is hosted on GitHub: https://github.com/RVV-karma/urlops
License
MIT License - see LICENSE for details.
Project details
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 urlops-1.0.5.tar.gz.
File metadata
- Download URL: urlops-1.0.5.tar.gz
- Upload date:
- Size: 21.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bb1465701b7ae51d5985c315320322ebf1976ce90ddfbc0885aaa6ac953d4795
|
|
| MD5 |
d63c7937718bd9756460112e66f1dff2
|
|
| BLAKE2b-256 |
dfd5e808014634a7fc265a9b4d88f4446a5fbb996c91d41dfa31570e32d33d25
|
File details
Details for the file urlops-1.0.5-py3-none-any.whl.
File metadata
- Download URL: urlops-1.0.5-py3-none-any.whl
- Upload date:
- Size: 11.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.8.18
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed99a5fb4e55528f06ab2e725bf5f4b029aee6c68d95e28a14939a6a3a8405af
|
|
| MD5 |
249089cf382bb818cce36ccedae90145
|
|
| BLAKE2b-256 |
f9fe66a223c961616813389ad7fe1ea56f2f002d368d7c762a86f799a62fc918
|