
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
social-links
Advanced tools
Python library to validate, sanitize, and detect social media URLs. Support for LinkedIn, Instagram, TikTok, X/Twitter, GitHub, Facebook, YouTube, and 50+ platforms. Features automatic URL normalization and zero dependencies. Easy to use, regex-powered, and customizable.
Python library to validate, sanitize, and detect social media URLs. Support for LinkedIn, Instagram, TikTok, X/Twitter, GitHub, Facebook, YouTube, and 65+ platforms. Features automatic URL normalization and zero dependencies. Easy to use, regex-powered, and customizable.
🚀 Try it interactively in your browser! Test the library with our Interactive Demo - no installation required.

pip install social-links
Or using uv:
uv pip install social-links
from sociallinks import detect_platform, sanitize, extract_id, is_valid, list_platforms
# Detect platform from URL
platform = detect_platform("https://www.linkedin.com/in/ysskrishna/")
print(platform) # "linkedin"
# Validate URL for a specific platform
is_valid_url = is_valid("linkedin", "https://www.linkedin.com/in/ysskrishna/")
print(is_valid_url) # True
# Sanitize URL to canonical format
sanitized = sanitize("linkedin", "https://www.linkedin.com/in/ysskrishna/")
print(sanitized) # "https://linkedin.com/in/ysskrishna"
# Extract username/ID from URL
user_id = extract_id("linkedin", "https://www.linkedin.com/in/ysskrishna/")
print(user_id) # "ysskrishna"
# List all supported platforms
platforms = list_platforms()
print(f"Supported platforms: {len(platforms)}") # Supported platforms: 65+
That's it! For most use cases, you don't need anything more. See Basic Usage for more examples, or Advanced Usage if you need custom platforms or configurations.
The library comes with 65+ predefined platforms:
The simplest way to use social-links is with module-level functions. These work out of the box with 50+ predefined platforms - no configuration needed!
from sociallinks import detect_platform
# Detect from full URL
detect_platform("https://github.com/ysskrishna") # "github"
detect_platform("https://x.com/ysskrishna") # "x"
detect_platform("https://example.com") # None
# Works with various URL formats
detect_platform("http://linkedin.com/in/ysskrishna")
detect_platform("www.facebook.com/ysskrishna")
detect_platform(" https://instagram.com/ysskrishna ") # Handles whitespace
from sociallinks import is_valid
# Validate against specific platform
is_valid("linkedin", "https://www.linkedin.com/in/ysskrishna/") # True
is_valid("linkedin", "https://example.com") # False
is_valid("github", "https://github.com/ysskrishna") # True
from sociallinks import sanitize
# Normalize to canonical format
sanitize("linkedin", "https://www.linkedin.com/in/ysskrishna/")
# Returns: "https://linkedin.com/in/ysskrishna"
sanitize("github", "http://www.github.com/ysskrishna")
# Returns: "https://github.com/ysskrishna"
sanitize("x", "https://twitter.com/ysskrishna")
# Returns: "https://x.com/ysskrishna"
from sociallinks import extract_id
# Extract username/profile ID from URL
extract_id("linkedin", "https://www.linkedin.com/in/ysskrishna/") # "ysskrishna"
extract_id("github", "https://github.com/ysskrishna") # "ysskrishna"
extract_id("x", "https://twitter.com/ysskrishna") # "ysskrishna"
# Works with company/org URLs too
extract_id("linkedin", "https://linkedin.com/company/acme") # "acme"
from sociallinks import list_platforms
# Get all available platforms
platforms = list_platforms()
# Returns: ["behance", "dev_to", "dribbble", "github", "linkedin", ...]
print(f"Supported platforms: {len(platforms)}") # 50+
For custom configurations, custom platforms, or programmatic platform management, use the SocialLinks class directly instead of the module-level functions.
Use the class API when you need to:
The SocialLinks class provides the same methods as module-level functions, but with additional configuration options:
from sociallinks import SocialLinks
sl = SocialLinks()
# Same methods as module functions
sl.detect_platform("https://github.com/ysskrishna") # "github"
sl.is_valid("linkedin", "https://linkedin.com/in/user") # True
sl.sanitize("github", "https://github.com/user") # "https://github.com/user"
sl.extract_id("github", "https://github.com/user") # "user"
sl.list_platforms() # ["behance", "dev_to", "dribbble", ...]
import re
# Start with empty platform list (useful for custom platforms only)
sl = SocialLinks(use_predefined_platforms=False)
# Configure regex compilation flags
sl = SocialLinks(regex_flags=re.IGNORECASE | re.MULTILINE)
A platform configuration is a list of dictionaries. Each dictionary contains:
patterns: List of regex patterns that match URLs for this platformsanitized: Template string for the canonical URL formatMultiple dictionaries are useful when a platform has different URL types that normalize to different canonical forms (e.g., LinkedIn personal profiles /in/ vs company pages /company/).
Single dictionary - Multiple patterns sharing the same sanitization template:
platform_config = [{
"patterns": [
r"https?://(www\.)?example\.com/(?P<id>[A-Za-z0-9_]+)/?$",
r"https?://example\.com/user/(?P<id>[A-Za-z0-9_]+)/?$"
],
"sanitized": "https://example.com/{id}"
}]
Multiple dictionaries - Different URL formats with different sanitization templates (e.g., personal profiles vs company pages):
# Example: LinkedIn supports both personal profiles and company pages
platform_config = [
{
"patterns": [
r"https?://(www\.)?linkedin\.com/in/(?P<id>[A-Za-z0-9_-]+)/?$",
r"https?://linkedin\.com/mwlite/in/(?P<id>[A-Za-z0-9_-]+)/?$"
],
"sanitized": "https://linkedin.com/in/{id}" # Personal profiles
},
{
"patterns": [
r"https?://(www\.)?linkedin\.com/company/(?P<id>[A-Za-z0-9_-]+)/?$",
r"https?://(www\.)?linkedin\.com/school/(?P<id>[A-Za-z0-9_-]+)/?$"
],
"sanitized": "https://linkedin.com/company/{id}" # Company/school pages
}
]
Pattern Matching:
(?P<id>...) to capture identifiers (username, ID, etc.)detect_platform(): All patterns are checked (order-independent)sanitize(): Patterns are checked in order, and the first match is usedSanitization Template:
{id} (or other named groups from patterns) as placeholderssanitize()from sociallinks import SocialLinks
sl = SocialLinks(use_predefined_platforms=False)
# Define a custom platform
custom_platform = [{
"patterns": [
r"https?://(www\.)?example\.com/(?P<id>[A-Za-z0-9_]+)/?$",
r"https?://example\.com/user/(?P<id>[A-Za-z0-9_]+)/?$"
],
"sanitized": "https://example.com/{id}"
}]
# Register the platform
sl.set_platform("example", custom_platform)
# Use it
sl.detect_platform("https://example.com/user123") # "example"
sl.sanitize("example", "https://www.example.com/user123/") # "https://example.com/user123"
When a platform supports different URL formats that normalize to different canonical forms (e.g., personal profiles vs company pages):
from sociallinks import SocialLinks
sl = SocialLinks(use_predefined_platforms=False)
# Example: Platform with personal profiles and company pages
linkedin_style_platform = [
{
"patterns": [
r"https?://(www\.)?example\.com/profile/(?P<id>[A-Za-z0-9_-]+)/?$",
r"https?://example\.com/user/(?P<id>[A-Za-z0-9_-]+)/?$"
],
"sanitized": "https://example.com/profile/{id}" # Personal profiles
},
{
"patterns": [
r"https?://(www\.)?example\.com/company/(?P<id>[A-Za-z0-9_-]+)/?$",
r"https?://(www\.)?example\.com/org/(?P<id>[A-Za-z0-9_-]+)/?$"
],
"sanitized": "https://example.com/company/{id}" # Company pages
}
]
sl.set_platform("example", linkedin_style_platform)
# Personal profile URLs normalize to /profile/
sl.sanitize("example", "https://www.example.com/user/johndoe")
# Returns: "https://example.com/profile/johndoe"
# Company URLs normalize to /company/
sl.sanitize("example", "https://www.example.com/org/acme-corp")
# Returns: "https://example.com/company/acme-corp"
from sociallinks import SocialLinks
sl = SocialLinks()
# Get configuration for an existing platform
github_config = sl.get_platform("github")
print(github_config) # See the patterns and sanitized template
# List all available platforms
platforms = sl.list_platforms()
# Returns: ["behance", "dev_to", "dribbble", "github", "linkedin", ...]
# Add a new platform (raises error if platform already exists)
custom_platform = [{
"patterns": [r"https?://example.com/(?P<id>[A-Za-z0-9_]+)"],
"sanitized": "https://example.com/{id}"
}]
sl.set_platform("example", custom_platform)
# Override an existing platform (including predefined ones)
sl.set_platform("github", custom_platform, override=True)
# Add multiple platforms at once
new_platforms = {
"platform1": [{
"patterns": [r"https?://example1.com/(?P<id>[A-Za-z0-9_]+)"],
"sanitized": "https://example1.com/{id}"
}],
"platform2": [{
"patterns": [r"https?://example2.com/(?P<id>[A-Za-z0-9_]+)"],
"sanitized": "https://example2.com/{id}"
}]
}
sl.set_platforms(new_platforms, override=False) # Raises error if any exist
sl.set_platforms(new_platforms, override=True) # Overrides existing platforms
# Get existing configuration
github_config = sl.get_platform("github")
# Modify and override
custom_github = [{
"patterns": [r"https?://github\.com/(?P<id>[A-Za-z0-9_]+)/?$"],
"sanitized": "https://github.com/{id}"
}]
sl.set_platform("github", custom_github, override=True)
# Delete a single platform
sl.delete_platform("custom_platform")
# Delete multiple platforms
sl.delete_platforms(["platform1", "platform2"])
# Clear all platforms
sl.clear_platforms()
Here's a complete example showing how to build a custom platform manager:
from sociallinks import SocialLinks
# Start with predefined platforms
sl = SocialLinks()
# Add a custom platform
my_platform = [{
"patterns": [
r"https?://(www\.)?mysite\.com/profile/(?P<id>[A-Za-z0-9_]+)/?$",
r"https?://mysite\.com/u/(?P<id>[A-Za-z0-9_]+)/?$"
],
"sanitized": "https://mysite.com/profile/{id}"
}]
sl.set_platform("mysite", my_platform)
# Use it
url = "https://www.mysite.com/u/johndoe"
platform = sl.detect_platform(url) # "mysite"
sanitized = sl.sanitize(platform, url) # "https://mysite.com/profile/johndoe"
user_id = sl.extract_id(platform, url) # "johndoe"
is_valid = sl.is_valid(platform, url) # True
# View all platforms
all_platforms = sl.list_platforms()
print(f"Total platforms: {len(all_platforms)}")
See CHANGELOG.md for a detailed list of changes and version history.
The following improvements are planned for upcoming releases:
Contributions are welcome! Please read our Contributing Guide for details on our code of conduct, development setup, and the process for submitting pull requests.
If you find this library helpful:
This package is inspired by the social-links npm package by gkucmierz.
MIT © Y. Siva Sai Krishna - see LICENSE file for details.
Author's GitHub • Author's LinkedIn • Report Issues • Package on PyPI • Package Documentation • Interactive Demo
FAQs
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.