urlpath


Nameurlpath JSON
Version 2.0.0 PyPI version JSON
download
home_pageNone
SummaryObject-oriented URL from urllib.parse and pathlib
upload_time2025-10-13 21:34:27
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords http pathlib requests uri url urllib
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # URLPath

URLPath provides URL manipulator class that extends [`pathlib.PurePath`](https://docs.python.org/3/library/pathlib.html#pure-paths).

[![Tests](https://github.com/brandonschabell/urlpath/actions/workflows/test.yml/badge.svg)](https://github.com/brandonschabell/urlpath/actions/workflows/test.yml)
[![PyPI version](https://img.shields.io/pypi/v/urlpath.svg)](https://pypi.python.org/pypi/urlpath)
[![Downloads](https://pepy.tech/badge/urlpath)](https://pepy.tech/project/urlpath)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python Versions](https://img.shields.io/pypi/pyversions/urlpath.svg)](https://pypi.org/project/urlpath/)

## Dependencies

* Python 3.9–3.14
* [Requests](http://docs.python-requests.org/)
* [JMESPath](https://pypi.org/project/jmespath/) (Optional)
* [WebOb](http://webob.org/) (Optional)

## Install

```bash
pip install urlpath
```

## Examples

```python
from urlpath import URL

# Create URL object
url = URL(
    'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment')

# Representation
assert str(url) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'
assert url.as_uri() == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'
assert url.as_posix() == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'

# Access pathlib.PurePath compatible properties
assert url.drive == 'https://username:password@secure.example.com:1234'
assert url.root == '/'
assert url.anchor == 'https://username:password@secure.example.com:1234/'
assert url.path == '/path/to/file.ext'
assert url.name == 'file.ext'
assert url.suffix == '.ext'
assert url.suffixes == ['.ext']
assert url.stem == 'file'
assert url.parts == ('https://username:password@secure.example.com:1234/', 'path', 'to', 'file.ext')
assert str(url.parent) == 'https://username:password@secure.example.com:1234/path/to'

# Access scheme
assert url.scheme == 'https'

# Access netloc
assert url.netloc == 'username:password@secure.example.com:1234'
assert url.username == 'username'
assert url.password == 'password'
assert url.hostname == 'secure.example.com'
assert url.port == 1234

# Access query
assert url.query == 'field1=1&field2=2&field1=3'
assert url.form_fields == (('field1', '1'), ('field2', '2'), ('field1', '3'))
assert 'field1' in url.form
assert url.form.get_one('field1') == '1'
assert url.form.get_one('field3') is None

# Access fragment
assert url.fragment == 'fragment'

# Path operations
assert str(url / 'suffix') == 'https://username:password@secure.example.com:1234/path/to/file.ext/suffix'
assert str(url / '../../rel') == 'https://username:password@secure.example.com:1234/path/to/file.ext/../../rel'
assert str((url / '../../rel').resolve()) == 'https://username:password@secure.example.com:1234/path/rel'
assert str(url / '/') == 'https://username:password@secure.example.com:1234/'
assert str(url / 'http://example.com/') == 'http://example.com/'

# Replace components
assert str(url.with_scheme('http')) == 'http://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'
assert str(url.with_netloc('www.example.com')) == 'https://www.example.com/path/to/file.ext?field1=1&field2=2&field1=3#fragment'
assert str(url.with_userinfo('joe', 'pa33')) == 'https://joe:pa33@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'
assert str(url.with_hostinfo('example.com', 8080)) == 'https://username:password@example.com:8080/path/to/file.ext?field1=1&field2=2&field1=3#fragment'
assert str(url.with_fragment('new fragment')) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#new fragment'
assert str(url.with_components(username=None, password=None, query='query', fragment='frag')) == 'https://secure.example.com:1234/path/to/file.ext?query#frag'

# Replace query
assert str(url.with_query({'field3': '3', 'field4': [1, 2, 3]})) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field3=3&field4=1&field4=2&field4=3#fragment'
assert str(url.with_query(field3='3', field4=[1, 2, 3])) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field3=3&field4=1&field4=2&field4=3#fragment'
assert str(url.with_query('query')) == 'https://username:password@secure.example.com:1234/path/to/file.ext?query#fragment'
assert str(url.with_query(None)) == 'https://username:password@secure.example.com:1234/path/to/file.ext#fragment'

# Amend query
assert str(url.with_query(field1='1').add_query(field2=2)) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2#fragment'
```

### HTTP requests

URLPath provides convenient methods for making HTTP requests:

```python
from urlpath import URL

# GET request
url = URL('https://httpbin.org/get')
response = url.get()
assert response.status_code == 200

# POST request
url = URL('https://httpbin.org/post')
response = url.post(data={'key': 'value'})
assert response.status_code == 200

# DELETE request
url = URL('https://httpbin.org/delete')
response = url.delete()
assert response.status_code == 200

# PATCH request
url = URL('https://httpbin.org/patch')
response = url.patch(data={'key': 'value'})
assert response.status_code == 200

# PUT request
url = URL('https://httpbin.org/put')
response = url.put(data={'key': 'value'})
assert response.status_code == 200
```

### Jail

```python
from urlpath import URL

root = 'http://www.example.com/app/'
current = 'http://www.example.com/app/path/to/content'
url = URL(root).jailed / current
assert str(url / '/root') == 'http://www.example.com/app/root'
assert str((url / '../../../../../../root').resolve()) == 'http://www.example.com/app/root'
assert str(url / 'http://localhost/') == 'http://www.example.com/app/'
assert str(url / 'http://www.example.com/app/file') == 'http://www.example.com/app/file'
```

### Trailing separator will be retained

```python
from urlpath import URL

url = URL('http://www.example.com/path/with/trailing/sep/')
assert str(url).endswith('/')
assert url.trailing_sep == '/'
assert url.name == 'sep'
assert url.path == '/path/with/trailing/sep/'
assert url.parts[-1] == 'sep'

url = URL('http://www.example.com/path/without/trailing/sep')
assert not str(url).endswith('/')
assert url.trailing_sep == ''
assert url.name == 'sep'
assert url.path == '/path/without/trailing/sep'
assert url.parts[-1] == 'sep'
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "urlpath",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "http, pathlib, requests, uri, url, urllib",
    "author": null,
    "author_email": "Brandon Schabell <brandonschabell@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/d4/be/0a8a0e30003112a6e0a4d356f2832ca4aa497f0a48a5e1fa6a8e42805659/urlpath-2.0.0.tar.gz",
    "platform": null,
    "description": "# URLPath\n\nURLPath provides URL manipulator class that extends [`pathlib.PurePath`](https://docs.python.org/3/library/pathlib.html#pure-paths).\n\n[![Tests](https://github.com/brandonschabell/urlpath/actions/workflows/test.yml/badge.svg)](https://github.com/brandonschabell/urlpath/actions/workflows/test.yml)\n[![PyPI version](https://img.shields.io/pypi/v/urlpath.svg)](https://pypi.python.org/pypi/urlpath)\n[![Downloads](https://pepy.tech/badge/urlpath)](https://pepy.tech/project/urlpath)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Python Versions](https://img.shields.io/pypi/pyversions/urlpath.svg)](https://pypi.org/project/urlpath/)\n\n## Dependencies\n\n* Python 3.9\u20133.14\n* [Requests](http://docs.python-requests.org/)\n* [JMESPath](https://pypi.org/project/jmespath/) (Optional)\n* [WebOb](http://webob.org/) (Optional)\n\n## Install\n\n```bash\npip install urlpath\n```\n\n## Examples\n\n```python\nfrom urlpath import URL\n\n# Create URL object\nurl = URL(\n    'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment')\n\n# Representation\nassert str(url) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'\nassert url.as_uri() == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'\nassert url.as_posix() == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'\n\n# Access pathlib.PurePath compatible properties\nassert url.drive == 'https://username:password@secure.example.com:1234'\nassert url.root == '/'\nassert url.anchor == 'https://username:password@secure.example.com:1234/'\nassert url.path == '/path/to/file.ext'\nassert url.name == 'file.ext'\nassert url.suffix == '.ext'\nassert url.suffixes == ['.ext']\nassert url.stem == 'file'\nassert url.parts == ('https://username:password@secure.example.com:1234/', 'path', 'to', 'file.ext')\nassert str(url.parent) == 'https://username:password@secure.example.com:1234/path/to'\n\n# Access scheme\nassert url.scheme == 'https'\n\n# Access netloc\nassert url.netloc == 'username:password@secure.example.com:1234'\nassert url.username == 'username'\nassert url.password == 'password'\nassert url.hostname == 'secure.example.com'\nassert url.port == 1234\n\n# Access query\nassert url.query == 'field1=1&field2=2&field1=3'\nassert url.form_fields == (('field1', '1'), ('field2', '2'), ('field1', '3'))\nassert 'field1' in url.form\nassert url.form.get_one('field1') == '1'\nassert url.form.get_one('field3') is None\n\n# Access fragment\nassert url.fragment == 'fragment'\n\n# Path operations\nassert str(url / 'suffix') == 'https://username:password@secure.example.com:1234/path/to/file.ext/suffix'\nassert str(url / '../../rel') == 'https://username:password@secure.example.com:1234/path/to/file.ext/../../rel'\nassert str((url / '../../rel').resolve()) == 'https://username:password@secure.example.com:1234/path/rel'\nassert str(url / '/') == 'https://username:password@secure.example.com:1234/'\nassert str(url / 'http://example.com/') == 'http://example.com/'\n\n# Replace components\nassert str(url.with_scheme('http')) == 'http://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'\nassert str(url.with_netloc('www.example.com')) == 'https://www.example.com/path/to/file.ext?field1=1&field2=2&field1=3#fragment'\nassert str(url.with_userinfo('joe', 'pa33')) == 'https://joe:pa33@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#fragment'\nassert str(url.with_hostinfo('example.com', 8080)) == 'https://username:password@example.com:8080/path/to/file.ext?field1=1&field2=2&field1=3#fragment'\nassert str(url.with_fragment('new fragment')) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2&field1=3#new fragment'\nassert str(url.with_components(username=None, password=None, query='query', fragment='frag')) == 'https://secure.example.com:1234/path/to/file.ext?query#frag'\n\n# Replace query\nassert str(url.with_query({'field3': '3', 'field4': [1, 2, 3]})) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field3=3&field4=1&field4=2&field4=3#fragment'\nassert str(url.with_query(field3='3', field4=[1, 2, 3])) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field3=3&field4=1&field4=2&field4=3#fragment'\nassert str(url.with_query('query')) == 'https://username:password@secure.example.com:1234/path/to/file.ext?query#fragment'\nassert str(url.with_query(None)) == 'https://username:password@secure.example.com:1234/path/to/file.ext#fragment'\n\n# Amend query\nassert str(url.with_query(field1='1').add_query(field2=2)) == 'https://username:password@secure.example.com:1234/path/to/file.ext?field1=1&field2=2#fragment'\n```\n\n### HTTP requests\n\nURLPath provides convenient methods for making HTTP requests:\n\n```python\nfrom urlpath import URL\n\n# GET request\nurl = URL('https://httpbin.org/get')\nresponse = url.get()\nassert response.status_code == 200\n\n# POST request\nurl = URL('https://httpbin.org/post')\nresponse = url.post(data={'key': 'value'})\nassert response.status_code == 200\n\n# DELETE request\nurl = URL('https://httpbin.org/delete')\nresponse = url.delete()\nassert response.status_code == 200\n\n# PATCH request\nurl = URL('https://httpbin.org/patch')\nresponse = url.patch(data={'key': 'value'})\nassert response.status_code == 200\n\n# PUT request\nurl = URL('https://httpbin.org/put')\nresponse = url.put(data={'key': 'value'})\nassert response.status_code == 200\n```\n\n### Jail\n\n```python\nfrom urlpath import URL\n\nroot = 'http://www.example.com/app/'\ncurrent = 'http://www.example.com/app/path/to/content'\nurl = URL(root).jailed / current\nassert str(url / '/root') == 'http://www.example.com/app/root'\nassert str((url / '../../../../../../root').resolve()) == 'http://www.example.com/app/root'\nassert str(url / 'http://localhost/') == 'http://www.example.com/app/'\nassert str(url / 'http://www.example.com/app/file') == 'http://www.example.com/app/file'\n```\n\n### Trailing separator will be retained\n\n```python\nfrom urlpath import URL\n\nurl = URL('http://www.example.com/path/with/trailing/sep/')\nassert str(url).endswith('/')\nassert url.trailing_sep == '/'\nassert url.name == 'sep'\nassert url.path == '/path/with/trailing/sep/'\nassert url.parts[-1] == 'sep'\n\nurl = URL('http://www.example.com/path/without/trailing/sep')\nassert not str(url).endswith('/')\nassert url.trailing_sep == ''\nassert url.name == 'sep'\nassert url.path == '/path/without/trailing/sep'\nassert url.parts[-1] == 'sep'\n```\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Object-oriented URL from urllib.parse and pathlib",
    "version": "2.0.0",
    "project_urls": {
        "Download": "https://pypi.org/project/urlpath/",
        "Homepage": "https://github.com/brandonschabell/urlpath",
        "Issues": "https://github.com/brandonschabell/urlpath/issues",
        "Repository": "https://github.com/brandonschabell/urlpath"
    },
    "split_keywords": [
        "http",
        " pathlib",
        " requests",
        " uri",
        " url",
        " urllib"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "c0822cd3516fdb5d2bf7fc8383375a62137111405c649d1ae915e826beded30f",
                "md5": "d206ebf1257e6caafd00bf969f919ef6",
                "sha256": "f5a337bc3bc9f41793d67d72cc0290925998c29acc2ff8f1692b0c2dba4c3728"
            },
            "downloads": -1,
            "filename": "urlpath-2.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d206ebf1257e6caafd00bf969f919ef6",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 21076,
            "upload_time": "2025-10-13T21:34:26",
            "upload_time_iso_8601": "2025-10-13T21:34:26.648947Z",
            "url": "https://files.pythonhosted.org/packages/c0/82/2cd3516fdb5d2bf7fc8383375a62137111405c649d1ae915e826beded30f/urlpath-2.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "d4be0a8a0e30003112a6e0a4d356f2832ca4aa497f0a48a5e1fa6a8e42805659",
                "md5": "fa321a09de8d2c0693788a5019671867",
                "sha256": "321b932709982079e71deddb4af56ffe3447a9596faa895de19cf0cbee23b239"
            },
            "downloads": -1,
            "filename": "urlpath-2.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "fa321a09de8d2c0693788a5019671867",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 21013,
            "upload_time": "2025-10-13T21:34:27",
            "upload_time_iso_8601": "2025-10-13T21:34:27.960913Z",
            "url": "https://files.pythonhosted.org/packages/d4/be/0a8a0e30003112a6e0a4d356f2832ca4aa497f0a48a5e1fa6a8e42805659/urlpath-2.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-13 21:34:27",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "brandonschabell",
    "github_project": "urlpath",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "urlpath"
}
        
Elapsed time: 2.09292s