0
# URL Modification Operations
1
2
Methods for creating modified versions of URLs by changing individual components. All URL objects are immutable, so modification methods return new URL instances rather than modifying the original.
3
4
## Capabilities
5
6
### Component Modification Methods
7
8
Replace individual URL components with new values while preserving other components.
9
10
```python { .api }
11
def with_scheme(self, scheme: str) -> "URL":
12
"""
13
Return URL with new scheme.
14
15
Args:
16
scheme (str): New scheme (http, https, ftp, etc.)
17
18
Returns:
19
URL: New URL with updated scheme
20
21
Raises:
22
ValueError: If scheme is invalid
23
"""
24
25
def with_user(self, user: str | None) -> "URL":
26
"""
27
Return URL with new user component.
28
29
Args:
30
user (str, optional): Username for authentication, None to remove
31
32
Returns:
33
URL: New URL with updated user component
34
"""
35
36
def with_password(self, password: str | None) -> "URL":
37
"""
38
Return URL with new password component.
39
40
Args:
41
password (str, optional): Password for authentication, None to remove
42
43
Returns:
44
URL: New URL with updated password component
45
"""
46
47
def with_host(self, host: str) -> "URL":
48
"""
49
Return URL with new host.
50
51
Args:
52
host (str): New hostname or IP address
53
54
Returns:
55
URL: New URL with updated host
56
57
Raises:
58
ValueError: If host is invalid
59
"""
60
61
def with_port(self, port: int | None) -> "URL":
62
"""
63
Return URL with new port.
64
65
Args:
66
port (int, optional): Port number, None to remove explicit port
67
68
Returns:
69
URL: New URL with updated port
70
71
Raises:
72
ValueError: If port is out of valid range (1-65535)
73
"""
74
75
def with_path(self, path: str, *, encoded: bool = False,
76
keep_query: bool = False, keep_fragment: bool = False) -> "URL":
77
"""
78
Return URL with new path.
79
80
Args:
81
path (str): New path component
82
encoded (bool): Whether path is already encoded
83
keep_query (bool): Whether to preserve existing query parameters
84
keep_fragment (bool): Whether to preserve existing fragment
85
86
Returns:
87
URL: New URL with updated path
88
"""
89
90
def with_fragment(self, fragment: str | None) -> "URL":
91
"""
92
Return URL with new fragment.
93
94
Args:
95
fragment (str, optional): Fragment identifier, None to remove
96
97
Returns:
98
URL: New URL with updated fragment
99
"""
100
```
101
102
### Filename Component Modification
103
104
Modify filename and extension components of the URL path.
105
106
```python { .api }
107
def with_name(self, name: str, *, keep_query: bool = False,
108
keep_fragment: bool = False) -> "URL":
109
"""
110
Return URL with new filename component.
111
112
Args:
113
name (str): New filename (last path segment)
114
keep_query (bool): Whether to preserve existing query parameters
115
keep_fragment (bool): Whether to preserve existing fragment
116
117
Returns:
118
URL: New URL with updated filename
119
120
Raises:
121
ValueError: If name contains path separators
122
"""
123
124
def with_suffix(self, suffix: str, *, keep_query: bool = False,
125
keep_fragment: bool = False) -> "URL":
126
"""
127
Return URL with new file extension.
128
129
Args:
130
suffix (str): New file extension (should include leading dot)
131
keep_query (bool): Whether to preserve existing query parameters
132
keep_fragment (bool): Whether to preserve existing fragment
133
134
Returns:
135
URL: New URL with updated file extension
136
"""
137
```
138
139
### Query Parameter Modification
140
141
Replace, extend, or modify query parameters. See [Query Parameter Handling](./query-handling.md) for detailed query manipulation methods.
142
143
```python { .api }
144
def with_query(self, query: Query = None, **kwargs: QueryVariable) -> "URL":
145
"""
146
Return URL with completely new query parameters.
147
148
Args:
149
query (Query, optional): Query parameters as dict, sequence, or string
150
**kwargs: Query parameters as keyword arguments
151
152
Returns:
153
URL: New URL with updated query parameters
154
"""
155
156
def extend_query(self, query: Query = None, **kwargs: QueryVariable) -> "URL":
157
"""
158
Return URL with additional query parameters.
159
160
Args:
161
query (Query, optional): Additional query parameters
162
**kwargs: Additional query parameters as keyword arguments
163
164
Returns:
165
URL: New URL with extended query parameters
166
"""
167
168
def update_query(self, query: Query = None, **kwargs: QueryVariable) -> "URL":
169
"""
170
Return URL with updated query parameters (merge with existing).
171
172
Args:
173
query (Query, optional): Query parameters to update
174
**kwargs: Query parameters as keyword arguments
175
176
Returns:
177
URL: New URL with updated query parameters
178
"""
179
180
def without_query_params(self, *query_params: str) -> "URL":
181
"""
182
Return URL without specified query parameters.
183
184
Args:
185
*query_params (str): Names of query parameters to remove
186
187
Returns:
188
URL: New URL with specified parameters removed
189
"""
190
```
191
192
### Operator Overloads
193
194
Convenient operators for common URL modifications.
195
196
```python { .api }
197
def __truediv__(self, name: str) -> "URL":
198
"""
199
Join URL with path component using / operator.
200
201
Args:
202
name (str): Path component to append
203
204
Returns:
205
URL: New URL with appended path component
206
"""
207
208
def __mod__(self, query: Query) -> "URL":
209
"""
210
Add query parameters using % operator.
211
212
Args:
213
query (Query): Query parameters to add
214
215
Returns:
216
URL: New URL with added query parameters
217
"""
218
```
219
220
## Usage Examples
221
222
### Basic Component Modification
223
224
```python
225
from yarl import URL
226
227
base_url = URL('https://example.com:8080/api/v1/users?limit=10#section')
228
229
# Modify individual components
230
https_url = base_url.with_scheme('https')
231
new_host = base_url.with_host('api.example.com')
232
std_port = base_url.with_port(None) # Remove explicit port
233
new_path = base_url.with_path('/api/v2/users')
234
no_fragment = base_url.with_fragment(None)
235
236
print(new_host) # https://api.example.com:8080/api/v1/users?limit=10#section
237
```
238
239
### Authentication Modification
240
241
```python
242
from yarl import URL
243
244
url = URL('https://example.com/api')
245
246
# Add authentication
247
auth_url = url.with_user('admin').with_password('secret')
248
print(auth_url) # https://admin:secret@example.com/api
249
250
# Remove authentication
251
no_auth = auth_url.with_user(None).with_password(None)
252
print(no_auth) # https://example.com/api
253
```
254
255
### Path and Filename Modification
256
257
```python
258
from yarl import URL
259
260
file_url = URL('https://example.com/documents/report.pdf')
261
262
# Change filename
263
new_file = file_url.with_name('summary.pdf')
264
print(new_file) # https://example.com/documents/summary.pdf
265
266
# Change extension
267
txt_file = file_url.with_suffix('.txt')
268
print(txt_file) # https://example.com/documents/report.txt
269
270
# Change path entirely
271
api_url = file_url.with_path('/api/v1/data')
272
print(api_url) # https://example.com/api/v1/data
273
```
274
275
### Query Parameter Modification
276
277
```python
278
from yarl import URL
279
280
api_url = URL('https://api.example.com/users?active=true&limit=10')
281
282
# Replace all query parameters
283
new_query = api_url.with_query({'status': 'pending', 'page': 1})
284
print(new_query) # https://api.example.com/users?status=pending&page=1
285
286
# Add query parameters
287
extended = api_url.extend_query({'sort': 'name'})
288
print(extended) # https://api.example.com/users?active=true&limit=10&sort=name
289
290
# Update specific parameters
291
updated = api_url.update_query({'limit': 50, 'offset': 20})
292
print(updated) # https://api.example.com/users?active=true&limit=50&offset=20
293
294
# Remove parameters
295
cleaned = api_url.without_query_params('limit', 'active')
296
print(cleaned) # https://api.example.com/users
297
```
298
299
### Using Operators
300
301
```python
302
from yarl import URL
303
304
base_url = URL('https://api.example.com')
305
306
# Use / operator to append paths
307
users_url = base_url / 'users' / '123' / 'profile'
308
print(users_url) # https://api.example.com/users/123/profile
309
310
# Use % operator to add query parameters
311
query_url = users_url % {'include': 'permissions', 'format': 'json'}
312
print(query_url) # https://api.example.com/users/123/profile?include=permissions&format=json
313
314
# Chain operations
315
final_url = (base_url
316
/ 'api' / 'v1' / 'users'
317
% {'active': True, 'limit': 50}
318
).with_fragment('results')
319
print(final_url) # https://api.example.com/api/v1/users?active=True&limit=50#results
320
```
321
322
### Method Chaining
323
324
```python
325
from yarl import URL
326
327
# Chain multiple modifications
328
result = (URL('http://old.example.com:8080/old/path?old=param')
329
.with_scheme('https')
330
.with_host('new.example.com')
331
.with_port(None)
332
.with_path('/new/api/endpoint')
333
.with_query({'version': '2', 'format': 'json'})
334
.with_fragment('response'))
335
336
print(result) # https://new.example.com/new/api/endpoint?version=2&format=json#response
337
```