| Name | urlpath JSON |
| Version |
2.0.0
JSON |
| download |
| home_page | None |
| Summary | Object-oriented URL from urllib.parse and pathlib |
| upload_time | 2025-10-13 21:34:27 |
| maintainer | None |
| docs_url | None |
| author | None |
| requires_python | >=3.9 |
| license | None |
| 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).
[](https://github.com/brandonschabell/urlpath/actions/workflows/test.yml)
[](https://pypi.python.org/pypi/urlpath)
[](https://pepy.tech/project/urlpath)
[](https://opensource.org/licenses/MIT)
[](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[](https://github.com/brandonschabell/urlpath/actions/workflows/test.yml)\n[](https://pypi.python.org/pypi/urlpath)\n[](https://pepy.tech/project/urlpath)\n[](https://opensource.org/licenses/MIT)\n[](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"
}