CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-furl

URL manipulation made simple.

65

1.58x
Overview
Eval results
Files

fragment.mddocs/

Fragment Handling

The Fragment class manages URL fragments with support for both path and query components within the fragment. It provides flexible fragment manipulation including custom separators and independent path/query handling.

Capabilities

Fragment Construction and Loading

Create and load fragment objects from strings with automatic parsing of path and query components.

class Fragment:
    def __init__(self, fragment='', strict=False):
        """
        Initialize a Fragment object.
        
        Args:
            fragment (str): Fragment string to parse
            strict (bool): Enable strict parsing mode
        """
        
    def load(self, fragment):
        """
        Load a fragment string into the Fragment object.
        
        Args:
            fragment (str): Fragment string to parse
            
        Returns:
            Fragment: Self for method chaining
        """

Usage:

from furl import Fragment

# Create from fragment string with path and query
f = Fragment('path/to/section?param=value&other=data')
print(f.path.segments)      # ['path', 'to', 'section']
print(f.query.params['param'])  # 'value'

# Create with just path
f = Fragment('simple/path')
print(f.path.segments)      # ['simple', 'path']
print(bool(f.query))        # False

# Create with just query
f = Fragment('?key=value&another=param')
print(bool(f.path))         # False
print(f.query.params['key']) # 'value'

Fragment Components

Access and manipulate fragment path and query components independently.

class Fragment:
    @property
    def path(self) -> 'Path':
        """
        Fragment path component (Path object).
        Independent of main URL path.
        """
        
    @property
    def query(self) -> 'Query':
        """
        Fragment query component (Query object).
        Independent of main URL query.
        """
        
    @property
    def separator(self) -> str | None:
        """
        Separator between fragment path and query.
        Usually '?' or None if no query.
        """
        
    @separator.setter
    def separator(self, separator: str | None):
        """Set fragment separator"""

Usage:

f = Fragment('docs/api?version=1&format=json')

# Access path component
print(f.path.segments)           # ['docs', 'api']
f.path.segments.append('users')
print(str(f.path))              # 'docs/api/users'

# Access query component
print(f.query.params['version']) # '1'
f.query.add({'limit': '10'})
print(str(f.query))             # 'version=1&format=json&limit=10'

# Check separator
print(f.separator)              # '?'

# Modify components independently
f.path.set('different/section')
f.query.set({'new': 'params'})
print(str(f))                   # 'different/section?new=params'

Fragment Manipulation

Add, set, and remove fragment components with method chaining support.

class Fragment:
    def add(self, path=None, args=None):
        """
        Add components to the fragment.
        
        Args:
            path (str): Path segments to add to fragment path
            args (dict): Query parameters to add to fragment query
            
        Returns:
            Fragment: Self for method chaining
        """
        
    def set(self, path=None, args=None, separator=None):
        """
        Set fragment components, replacing existing values.
        
        Args:
            path (str): Path to set for fragment
            args (dict): Query parameters to set for fragment
            separator (str): Separator between path and query
            
        Returns:
            Fragment: Self for method chaining
        """
        
    def remove(self, fragment=None, path=None, args=None):
        """
        Remove fragment components.
        
        Args:
            fragment (bool): Remove entire fragment if True
            path (str|bool): Path segments to remove or True for all
            args (list|bool): Query parameter keys to remove or True for all
            
        Returns:
            Fragment: Self for method chaining
        """

Usage:

f = Fragment('section1')

# Add path segments
f.add(path='subsection')
print(str(f))  # 'section1/subsection'

# Add query parameters
f.add(args={'filter': 'active', 'sort': 'name'})
print(str(f))  # 'section1/subsection?filter=active&sort=name'

# Set new components (replaces existing)
f.set(path='newpath', args={'key': 'value'})
print(str(f))  # 'newpath?key=value'

# Remove query parameters
f.remove(args=['key'])
print(str(f))  # 'newpath'

# Remove entire fragment
f.remove(fragment=True)
print(str(f))  # ''

Fragment String Operations

Convert fragments to strings and perform fragment operations.

class Fragment:
    def __str__(self) -> str:
        """
        Convert fragment to string.
        
        Returns:
            str: Fragment string with proper encoding
        """
        
    def __eq__(self, other) -> bool:
        """Check fragment equality"""
        
    def __bool__(self) -> bool:
        """Boolean evaluation (True if fragment has path or query)"""
        
    def asdict(self) -> dict:
        """
        Convert fragment to dictionary representation.
        
        Returns:
            dict: Dictionary with fragment components
        """

Usage:

f = Fragment('docs/api?version=2')

# String conversion
fragment_str = str(f)
print(fragment_str)  # 'docs/api?version=2'

# Fragment comparison
f1 = Fragment('path?key=value')
f2 = Fragment('path?key=value')
print(f1 == f2)  # True

# Boolean evaluation
empty_fragment = Fragment()
print(bool(empty_fragment))  # False

non_empty = Fragment('content')
print(bool(non_empty))  # True

# Dictionary representation
fragment_dict = f.asdict()
print(fragment_dict)  # Contains fragment metadata

Advanced Fragment Usage

Complex Fragment Paths

Handle complex path structures within fragments:

f = Fragment()

# Build complex path
f.path.segments = ['documentation', 'api', 'v2', 'authentication']
f.path.isabsolute = False  # Fragment paths can be relative

# Add query parameters
f.add(args={
    'section': 'oauth',
    'example': 'basic',
    'lang': 'python'
})

print(str(f))  # 'documentation/api/v2/authentication?section=oauth&example=basic&lang=python'

Fragment Query Parameters

Handle multiple values and complex query structures:

f = Fragment()

# Multiple values for parameters
f.query.params.addlist('tags', ['python', 'url', 'parsing'])
f.query.add({'priority': 'high', 'category': 'tutorial'})

print(str(f))  # '?tags=python&tags=url&tags=parsing&priority=high&category=tutorial'

# Access specific values
print(f.query.params.getlist('tags'))  # ['python', 'url', 'parsing']
print(f.query.params['priority'])      # 'high'

Custom Separators

Use custom separators between fragment path and query:

f = Fragment('path/to/content?param=value')

# Change separator
f.separator = ';'
print(str(f))  # 'path/to/content;param=value'

# Remove separator (query becomes part of path)
f.separator = None
# This merges query into path - use carefully

# Restore standard separator
f.separator = '?'

Fragment in URL Context

Fragments work within furl objects as part of complete URLs:

from furl import furl

url = furl('https://example.com/page')

# Set fragment with both path and query
url.fragment.set(path='section/overview', args={'highlight': 'introduction'})
print(url.url)  # 'https://example.com/page#section/overview?highlight=introduction'

# Add to existing fragment
url.fragment.add(path='details')
url.fragment.add(args={'expand': 'all'})
print(url.url)  # 'https://example.com/page#section/overview/details?highlight=introduction&expand=all'

# Fragment path is independent of main URL path
url.path.segments.append('api')
print(url.url)  # 'https://example.com/page/api#section/overview/details?highlight=introduction&expand=all'

Fragment Encoding

Fragments handle encoding similarly to paths and queries:

# Unicode in fragment paths
f = Fragment('文档/章节')
print(str(f))  # Properly encoded

# Special characters in fragment queries
f = Fragment()
f.add(args={'search': 'term with spaces & symbols!'})
print(str(f))  # '?search=term+with+spaces+%26+symbols%21'

# Mixed content
f = Fragment('path with spaces?key=value with & symbols')
print(str(f))  # Properly encoded path and query

Fragment Path vs Main Path

Fragment paths behave differently from main URL paths:

from furl import furl

url = furl('https://example.com/main/path')

# Main path must be absolute when netloc is present
print(url.path.isabsolute)  # True (read-only)

# Fragment path can be relative
url.fragment.path.segments = ['relative', 'fragment', 'path']
url.fragment.path.isabsolute = False
print(url.fragment.path.isabsolute)  # False (allowed)

print(url.url)  # 'https://example.com/main/path#relative/fragment/path'

Error Handling

Fragment objects handle various error conditions:

  • Invalid separators: Non-standard separators are handled gracefully
  • Encoding issues: Proper percent-encoding/decoding for all components
  • Empty components: Correct handling of fragments with only path or only query
  • Unicode support: Full Unicode support in both path and query components
  • Strict mode: Additional validation when strict=True

Install with Tessl CLI

npx tessl i tessl/pypi-furl

docs

core-url.md

fragment.md

index.md

path.md

query.md

utilities.md

tile.json