PyShortIO: A Pythonic Client for Short.io URL Shortening Service¶
Introduction¶
This notebook provides a comprehensive walkthrough of the PyShortIO library, a Python client for interacting with the Short.io URL shortening service. Short.io is a popular URL shortening service that provides a robust API for programmatically creating and managing shortened URLs.
PyShortIO is designed with a clean, well-documented API and comprehensive error handling, making it an excellent choice for Python developers looking to integrate Short.io functionality into their applications.
Let’s explore the key features and functionality of the PyShortIO library through practical examples.
Prerequisites¶
To use PyShortIO, you’ll need:
A Short.io account with API access
Your Short.io API token
A registered domain in your Short.io account
Installation¶
First, let’s install the PyShortIO library:
pip install pyshortio
Setting Up the Client¶
The first step in using PyShortIO is to create a client instance with your API token. The client will be our main interface for interacting with the Short.io API.
[1]:
from pathlib import Path
import pyshortio.api as pyshortio
# Replace with your actual Short.io API token
# API_TOKEN = "your_api_token_here"
API_TOKEN = Path.home().joinpath(".short.io", "sanhehu_esc", "sanhe-dev.txt").read_text().strip()
# Create a client instance
client = pyshortio.Client(token=API_TOKEN)
print(f"Client initialized with endpoint: {client.endpoint}")
Client initialized with endpoint: https://api.short.io
Finding Your Domain¶
Before creating shortened links, we need to identify the domain we’ll be working with. Short.io allows you to use your own custom domains for shortened URLs.
In this example, we’ll find a domain by its hostname and retrieve its ID, which we’ll need for various operations.
[2]:
# Replace with your actual Short.io domain
HOSTNAME = "pyshortio.short.gy"
# Get domain by hostname
response, domain = client.get_domain_by_hostname(hostname=HOSTNAME)
if domain:
print(f"Domain found: {domain.hostname}")
print(f"Domain ID: {domain.id}")
print(f"Domain state: {domain.state}")
print(f"Domain created at: {domain.created_at}")
# Store the domain ID for later use
domain_id = domain.id
else:
print(f"Domain {HOSTNAME} not found")
Domain found: pyshortio.short.gy
Domain ID: 1342190
Domain state: configured
Domain created at: 2025-04-20 16:07:15+00:00
Cleaning Up Existing Links¶
To start with a clean slate for our examples, we’ll delete any existing links on our domain. This is a good practice for testing and demonstration purposes.
[3]:
# Fetch all existing links
link_ids = []
for _, link_list in client.pagi_list_links(
domain_id=domain_id,
limit=100, # Fetch up to 100 links per page
):
for link in link_list:
link_ids.append(link.id)
# Delete all existing links if any were found
if len(link_ids):
response, success = client.batch_delete_links(link_ids=link_ids)
print(f"Deleted {len(link_ids)} existing links. Success: {success}")
else:
print("No existing links found to delete.")
Deleted 2 existing links. Success: True
Getting Domain Information¶
Now that we’ve set up our environment, let’s retrieve detailed information about our domain using its ID.
[4]:
# Get domain information using the domain ID
response, domain = client.get_domain(domain_id=domain_id)
# Display domain information
print(f"Domain ID: {domain.id}")
print(f"Hostname: {domain.hostname}")
print(f"Unicode Hostname: {domain.unicode_hostname}")
print(f"State: {domain.state}")
print(f"Created At: {domain.created_at}")
print(f"Updated At: {domain.updated_at}")
print(f"Team ID: {domain.team_id}")
print(f"Has Favicon: {domain.has_favicon}")
Domain ID: 1342190
Hostname: pyshortio.short.gy
Unicode Hostname: pyshortio.short.gy
State: configured
Created At: 2025-04-20 16:07:15+00:00
Updated At: 2025-04-20 16:07:15+00:00
Team ID: None
Has Favicon: False
Creating Your First Shortened Link¶
Now let’s create our first shortened link. We’ll use the create_link method to shorten a URL to the Short.io pricing page.
[5]:
# Create a shortened link to the Short.io pricing page
response, link = client.create_link(
hostname=HOSTNAME,
title="Short io pricing",
original_url="https://short.io/pricing/",
)
# Store this link for later use
link_pricing = link
# Display information about the newly created link
print(f"Link created successfully!")
print(f"ID: {link.id}")
print(f"Title: {link.title}")
print(f"Original URL: {link.original_url}")
print(f"Shortened URL: {link.short_url}")
print(f"Path: {link.path}")
print(f"Created At: {link.created_at}")
Link created successfully!
ID: lnk_5Dae_mcadseJwZnuDmoMVoUhYl
Title: Short io pricing
Original URL: https://short.io/pricing/
Shortened URL: https://pyshortio.short.gy/Yl3Hia
Path: Yl3Hia
Created At: 2025-04-21 03:41:29.569000+00:00
Creating Multiple Links in Batch¶
Instead of creating links one by one, Short.io allows you to create multiple links in a single API call using the batch creation feature. This is more efficient when you need to create several links at once.
[6]:
# Create multiple links in a batch
response, links = client.batch_create_links(
hostname=HOSTNAME,
links=[
{
"title": "Short io features",
"original_url": "https://short.io/features/",
},
{
"title": "Short io integrations",
"original_url": "https://short.io/integrations/",
},
],
)
# Store these links for later use
link_features = links[0]
link_integrations = links[1]
# Display information about the newly created links
print("Batch links created successfully!")
print("\nLink 1:")
print(f"Title: {link_features.title}")
print(f"Original URL: {link_features.original_url}")
print(f"Shortened URL: {link_features.short_url}")
print("\nLink 2:")
print(f"Title: {link_integrations.title}")
print(f"Original URL: {link_integrations.original_url}")
print(f"Shortened URL: {link_integrations.short_url}")
Batch links created successfully!
Link 1:
Title: Short io features
Original URL: https://short.io/features/
Shortened URL: https://pyshortio.short.gy/5fqCe1
Link 2:
Title: Short io integrations
Original URL: https://short.io/integrations/
Shortened URL: https://pyshortio.short.gy/EtC1pB
Listing Links with Pagination¶
Now that we have created some links, let’s learn how to list them. First, we’ll try listing with a limit to control how many links are returned per page.
[7]:
# List links with a limit of 2 per page
response, link_list = client.list_links(
domain_id=domain_id,
limit=2,
)
# Display the number of links returned and their details
print(f"Number of links returned: {len(link_list)}")
for i, link in enumerate(link_list, 1):
print(f"\nLink {i}:")
print(f"ID: {link.id}")
print(f"Title: {link.title}")
print(f"Original URL: {link.original_url}")
print(f"Shortened URL: {link.short_url}")
Number of links returned: 2
Link 1:
ID: lnk_5Dae_3mX7ICtE7IjxdM27NPROw
Title: Short io integrations
Original URL: https://short.io/integrations/
Shortened URL: https://pyshortio.short.gy/EtC1pB
Link 2:
ID: lnk_5Dae_DTNJvCr1elsn9NqyxoXMU
Title: Short io features
Original URL: https://short.io/features/
Shortened URL: https://pyshortio.short.gy/5fqCe1
Listing All Links¶
Now let’s list all links without specifying a limit. This will return all links on our domain.
[8]:
# List all links on the domain
response, link_list = client.list_links(
domain_id=domain_id,
)
# Display the number of links returned
print(f"Total number of links: {len(link_list)}")
# Show a summarized list of all links
for i, link in enumerate(link_list, 1):
print(f"{i}. {link.title} - {link.short_url}")
Total number of links: 3
1. Short io integrations - https://pyshortio.short.gy/EtC1pB
2. Short io features - https://pyshortio.short.gy/5fqCe1
3. Short io pricing - https://pyshortio.short.gy/Yl3Hia
Using a Higher Limit for Listing¶
Let’s try listing with a higher limit to ensure we retrieve all links in a single request.
[9]:
# List links with a higher limit
response, link_list = client.list_links(
domain_id=domain_id,
limit=100,
)
# Display the number of links returned
print(f"Number of links with limit=100: {len(link_list)}")
Number of links with limit=100: 3
Auto-Pagination with pagi_list_links¶
For cases where you might have many links spread across multiple pages, PyShortIO provides an auto-pagination feature. The pagi_list_links method automatically handles pagination for you.
[10]:
# Use auto-pagination to fetch links in multiple pages
paginator = client.pagi_list_links(
domain_id=domain_id,
limit=2, # This will split our 3 links into 2 pages
)
# Convert the paginator results to a list for easier handling
results = list(paginator)
# Display pagination results
print(f"Number of pages: {len(results)}")
print(f"Links in first page: {len(results[0][1])}")
print(f"Links in second page: {len(results[1][1])}")
# Display links from each page
print("\nLinks from first page:")
for link in results[0][1]:
print(f"- {link.title} ({link.short_url})")
print("\nLinks from second page:")
for link in results[1][1]:
print(f"- {link.title} ({link.short_url})")
Number of pages: 2
Links in first page: 2
Links in second page: 1
Links from first page:
- Short io integrations (https://pyshortio.short.gy/EtC1pB)
- Short io features (https://pyshortio.short.gy/5fqCe1)
Links from second page:
- Short io pricing (https://pyshortio.short.gy/Yl3Hia)
Getting OpenGraph Properties¶
Short.io can extract OpenGraph metadata from the original URLs. Let’s see how to retrieve this information for our pricing link.
[11]:
# Get OpenGraph properties for the pricing link
response, result = client.get_link_opengraph_properties(
domain_id=domain_id,
link_id=link_pricing.id,
)
# Display OpenGraph properties
print("OpenGraph Properties:")
for value in result:
print(value)
OpenGraph Properties:
Getting Link Information by ID¶
You can retrieve detailed information about a specific link using its ID.
[12]:
# Get information about the pricing link by its ID
response, link = client.get_link_info_by_link_id(link_id=link_pricing.id)
# Display link information
print(f"Link ID: {link.id}")
print(f"Title: {link.title}")
print(f"Original URL: {link.original_url}")
print(f"Shortened URL: {link.short_url}")
print(f"Created At: {link.created_at}")
Link ID: lnk_5Dae_mcadseJwZnuDmoMVoUhYl
Title: Short io pricing
Original URL: https://short.io/pricing/
Shortened URL: https://pyshortio.short.gy/Yl3Hia
Created At: 2025-04-21 03:41:29.569000+00:00
Handling Non-Existent Links¶
It’s important to handle cases where a link might not exist. Let’s try retrieving a non-existent link.
[13]:
# Try to get information about a non-existent link
response, link = client.get_link_info_by_link_id(
link_id="not-exists",
raise_for_status=False, # Prevent raising an exception for 404 responses
)
# Check if link exists
if link is None:
print("Link not found, as expected.")
else:
print("Unexpected: Link found.")
Link not found, as expected.
Getting Link Information by Path¶
You can also retrieve link information using the hostname and path components of the shortened URL.
[14]:
# Get link information by hostname and path
response, link = client.get_link_info_by_path(
hostname=HOSTNAME,
path=link_pricing.path,
)
# Display link information
print(f"Link ID: {link.id}")
print(f"Path: {link.path}")
print(f"Title: {link.title}")
print(f"Original URL: {link.original_url}")
Link ID: lnk_5Dae_mcadseJwZnuDmoMVoUhYl
Path: Yl3Hia
Title: Short io pricing
Original URL: https://short.io/pricing/
Handling Non-Existent Paths¶
Similar to handling non-existent links, let’s see how to handle a non-existent path.
[15]:
# Try to get information about a non-existent path
response, link = client.get_link_info_by_path(
hostname=HOSTNAME,
path="not-exists",
raise_for_status=False, # Prevent raising an exception for 404 responses
)
# Check if link exists
if link is None:
print("Path not found, as expected.")
else:
print("Unexpected: Path found.")
Path not found, as expected.
Finding Links by Original URL¶
Short.io allows you to find all shortened links that point to a specific original URL. This is useful when you want to check if a URL has already been shortened.
[16]:
# Find links by original URL
response, link_list = client.list_links_by_original_url(
hostname=HOSTNAME,
original_url=link_pricing.original_url,
)
# Display the number of links found
print(f"Number of links found: {len(link_list)}")
# Display information about the found links
for link in link_list:
print(f"ID: {link.id}")
print(f"Title: {link.title}")
print(f"Original URL: {link.original_url}")
print(f"Shortened URL: {link.short_url}")
Number of links found: 1
ID: lnk_5Dae_mcadseJwZnuDmoMVoUhYl
Title: Short io pricing
Original URL: https://short.io/pricing/
Shortened URL: https://pyshortio.short.gy/Yl3Hia
Searching for Non-Existent Original URLs¶
Let’s try searching for links with an original URL that doesn’t exist in our domain.
[17]:
# Search for links with a non-existent original URL
response, link_list = client.list_links_by_original_url(
hostname=HOSTNAME,
original_url="https://example.com/not-exists",
raise_for_status=False, # Prevent raising an exception for 404 responses
)
# Display the number of links found
print(f"Number of links found: {len(link_list)}")
Number of links found: 0
Listing Folders¶
Short.io allows you to organize your links into folders. Let’s list all folders in our domain.
[18]:
# List all folders in the domain
response, folder_list = client.list_folders(domain_id=domain_id)
# Display the number of folders
print(f"Number of folders: {len(folder_list)}")
# Display folder information if any exist
if len(folder_list) > 0:
for folder in folder_list:
print(f"Folder ID: {folder.id}")
print(f"Folder Name: {folder.name}")
else:
print("No folders found.")
Number of folders: 0
No folders found.
Handling Non-Existent Folders¶
Let’s try retrieving a non-existent folder.
[19]:
# Try to get information about a non-existent folder
response, folder = client.get_folder(
domain_id=domain_id,
folder_id="not-exists",
raise_for_status=False, # Prevent raising an exception for 404 responses
)
# Check if folder exists
if folder is None:
print("Folder not found, as expected.")
else:
print("Unexpected: Folder found.")
Folder not found, as expected.
Updating a Link¶
Now that we’ve explored various ways to retrieve link information, let’s update an existing link. We’ll modify the title and original URL of our pricing link.
[20]:
# Update the pricing link
response, link = client.update_link(
link_id=link_pricing.id,
title="Short io pricing updated",
original_url="https://short.io/pricing/updated",
)
# Display updated link information
print(f"Link updated successfully!")
print(f"ID: {link.id}")
print(f"Updated Title: {link.title}")
print(f"Updated Original URL: {link.original_url}")
print(f"Shortened URL: {link.short_url}")
Link updated successfully!
ID: lnk_5Dae_mcadseJwZnuDmoMVoUhYl
Updated Title: Short io pricing updated
Updated Original URL: https://short.io/pricing/updated
Shortened URL: https://pyshortio.short.gy/Yl3Hia
Verifying the Update¶
Let’s verify that our link was actually updated by retrieving it again.
[21]:
# Get the updated link to verify changes
response, link = client.get_link_info_by_link_id(link_id=link_pricing.id)
# Display updated link information
print(f"Link ID: {link.id}")
print(f"Title: {link.title}")
print(f"Original URL: {link.original_url}")
print(f"Shortened URL: {link.short_url}")
Link ID: lnk_5Dae_mcadseJwZnuDmoMVoUhYl
Title: Short io pricing updated
Original URL: https://short.io/pricing/updated
Shortened URL: https://pyshortio.short.gy/Yl3Hia
Handling Update for Non-Existent Links¶
Let’s try updating a non-existent link and see how to handle this scenario.
[22]:
# Try to update a non-existent link
response, link = client.update_link(
link_id="not-exists",
raise_for_status=False, # Prevent raising an exception for 404 responses
)
# Check if link exists
if link is None:
print("Link not found, update failed as expected.")
else:
print("Unexpected: Link updated.")
Link not found, update failed as expected.
Handling Invalid Link IDs¶
Let’s try updating a link with an invalid ID format.
[23]:
# Try to update a link with an invalid ID format
response, link = client.update_link(
link_id="lnk_1a2b_3333cccc4444dddd55555", # Invalid ID format
raise_for_status=False, # Prevent raising an exception for 400 responses
)
# Check if link exists
if link is None:
print("Invalid link ID, update failed as expected.")
else:
print("Unexpected: Link updated.")
Invalid link ID, update failed as expected.
Deleting a Link¶
Now let’s delete a link. We’ll delete the pricing link that we created earlier.
[24]:
# Delete the pricing link
response, success = client.delete_link(
link_id=link_pricing.id,
)
# Check if deletion was successful
if success:
print(f"Link deleted successfully!")
else:
print("Failed to delete link.")
Link deleted successfully!
Handling Deletion for Non-Existent Links¶
Let’s try deleting a non-existent link and see how to handle this scenario.
[25]:
# Try to delete a non-existent link
response, success = client.delete_link(
link_id="not-exists",
raise_for_status=False, # Prevent raising an exception for 404 responses
)
# Check if deletion was successful
if success:
print("Unexpected: Link deleted.")
else:
print("Failed to delete link, as expected for a non-existent link.")
Failed to delete link, as expected for a non-existent link.
Verifying Remaining Links¶
Finally, let’s verify that we now have one less link in our domain after the deletion.
[26]:
# List all links to verify the deletion
response, link_list = client.list_links(
domain_id=domain_id,
limit=100,
)
# Display the number of links
print(f"Number of links after deletion: {len(link_list)}")
# List all links
for i, link in enumerate(link_list, 1):
print(f"{i}. {link.title} - {link.short_url}")
Number of links after deletion: 2
1. Short io integrations - https://pyshortio.short.gy/EtC1pB
2. Short io features - https://pyshortio.short.gy/5fqCe1
Conclusion¶
In this notebook, we’ve explored the key features of the PyShortIO library for interacting with the Short.io URL shortening service. We’ve covered:
Setting up the client
Finding and retrieving domain information
Creating individual and batch links
Listing links with and without pagination
Retrieving link information in various ways
Updating links
Deleting links
Handling various error scenarios
PyShortIO provides a clean, Pythonic interface to Short.io’s API, making it easy to integrate URL shortening functionality into your Python applications.
For more details, refer to the official documentation and the API reference at the project’s GitHub repository: PyShortIO.