0
# Resource Management
1
2
FHIR resource instances with full CRUD capabilities, validation, serialization, and path-based data access. Resources act as dictionary-like objects with additional FHIR-specific functionality.
3
4
## Capabilities
5
6
### Resource CRUD Operations
7
8
Core operations for managing individual FHIR resources on the server.
9
10
```python { .api }
11
async def create(self, **kwargs):
12
"""
13
Create the resource on the server.
14
15
Parameters:
16
- **kwargs: Additional parameters for creation (e.g., conditional create)
17
18
Returns:
19
Self with server-assigned ID and metadata
20
21
Raises:
22
- OperationOutcome: If creation fails
23
"""
24
25
async def update(self, **kwargs):
26
"""
27
Update the existing resource on the server.
28
29
Parameters:
30
- **kwargs: Additional parameters for update
31
32
Returns:
33
Self with updated data and metadata
34
35
Raises:
36
- ResourceNotFound: If resource doesn't exist
37
- OperationOutcome: If update fails
38
"""
39
40
async def patch(self, **kwargs):
41
"""
42
Patch the existing resource on the server.
43
44
Parameters:
45
- **kwargs: Additional parameters for patch operation
46
47
Returns:
48
Self with patched data and metadata
49
50
Raises:
51
- ResourceNotFound: If resource doesn't exist
52
- OperationOutcome: If patch fails
53
"""
54
55
async def delete(self):
56
"""
57
Delete the resource from the server.
58
59
Raises:
60
- ResourceNotFound: If resource doesn't exist
61
- OperationOutcome: If deletion fails
62
"""
63
64
async def save(self, **kwargs):
65
"""
66
Save the resource (create if new, update if existing).
67
68
Parameters:
69
- **kwargs: Additional parameters for save operation
70
71
Returns:
72
Self with saved data and metadata
73
"""
74
75
async def refresh(self):
76
"""
77
Refresh resource data from the server.
78
79
Returns:
80
Self with current server data
81
82
Raises:
83
- ResourceNotFound: If resource no longer exists
84
"""
85
```
86
87
### Resource Validation
88
89
Validate resources against FHIR profiles and business rules.
90
91
```python { .api }
92
async def is_valid(self) -> bool:
93
"""
94
Validate resource using server $validate operation.
95
96
Returns:
97
True if resource is valid, False otherwise
98
"""
99
```
100
101
### Resource Conversion and Serialization
102
103
Convert resources to different formats and create references.
104
105
```python { .api }
106
def to_reference(self, **kwargs) -> FHIRReference:
107
"""
108
Convert resource to a reference.
109
110
Parameters:
111
- **kwargs: Additional reference attributes (display, type, etc.)
112
113
Returns:
114
Reference pointing to this resource
115
"""
116
117
def serialize(self) -> dict:
118
"""
119
Serialize resource to a plain dictionary.
120
121
Returns:
122
Dict representation suitable for JSON serialization
123
"""
124
```
125
126
### Path-Based Data Access
127
128
Access nested resource data using dot-notation paths.
129
130
```python { .api }
131
def get_by_path(self, path: str, default=None):
132
"""
133
Get value from resource using dot-separated path.
134
135
Parameters:
136
- path: Dot-separated path (e.g., 'name.0.family')
137
- default: Value to return if path not found
138
139
Returns:
140
Value at path or default
141
"""
142
```
143
144
### Resource Properties
145
146
Core properties for accessing resource metadata.
147
148
```python { .api }
149
@property
150
def resource_type(self) -> str:
151
"""The FHIR resource type (e.g., 'Patient', 'Observation')"""
152
153
@property
154
def id(self) -> str:
155
"""The resource identifier assigned by the server"""
156
157
@property
158
def reference(self) -> str:
159
"""Full reference string in format 'ResourceType/id'"""
160
```
161
162
## Usage Examples
163
164
### Basic Resource Operations
165
166
```python
167
import asyncio
168
from fhirpy import AsyncFHIRClient
169
170
async def basic_operations():
171
client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')
172
173
# Create a new patient
174
patient = client.resource('Patient',
175
name=[{
176
'family': 'Doe',
177
'given': ['John', 'William']
178
}],
179
gender='male',
180
birthDate='1990-01-01',
181
active=True
182
)
183
184
# Save to server (create)
185
await patient.create()
186
print(f"Created patient: {patient.id}")
187
188
# Update patient
189
patient['telecom'] = [{
190
'system': 'email',
191
'value': 'john.doe@example.com'
192
}]
193
await patient.save()
194
195
# Refresh from server
196
await patient.refresh()
197
198
# Delete patient
199
await patient.delete()
200
```
201
202
### Conditional Operations
203
204
```python
205
async def conditional_operations():
206
client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')
207
208
# Conditional create - only create if identifier doesn't exist
209
patient = client.resource('Patient',
210
identifier=[{
211
'system': 'http://example.org/ids',
212
'value': 'unique-id-123'
213
}],
214
name=[{'family': 'Smith', 'given': ['Jane']}]
215
)
216
217
await patient.create(ifNoneExist='identifier=unique-id-123')
218
219
# Conditional update - update only if version matches
220
patient['active'] = False
221
await patient.update(ifMatch='W/"1"')
222
```
223
224
### Resource Validation
225
226
```python
227
async def validation_example():
228
client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')
229
230
# Create patient with invalid data
231
patient = client.resource('Patient',
232
name=[{'family': ''}], # Empty family name
233
gender='invalid-gender' # Invalid gender value
234
)
235
236
# Validate before saving
237
is_valid = await patient.is_valid()
238
if not is_valid:
239
print("Patient has validation errors")
240
# Fix issues before saving
241
patient['name'][0]['family'] = 'ValidName'
242
patient['gender'] = 'unknown'
243
244
if await patient.is_valid():
245
await patient.create()
246
```
247
248
### Path-Based Data Access
249
250
```python
251
async def path_access_example():
252
client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')
253
254
patient = client.resource('Patient',
255
name=[
256
{
257
'family': 'Doe',
258
'given': ['John', 'William'],
259
'use': 'official'
260
},
261
{
262
'family': 'Smith',
263
'given': ['Johnny'],
264
'use': 'nickname'
265
}
266
],
267
address=[{
268
'line': ['123 Main St', 'Apt 4B'],
269
'city': 'Springfield',
270
'postalCode': '12345',
271
'country': 'US'
272
}]
273
)
274
275
# Access nested data using paths
276
family_name = patient.get_by_path('name.0.family') # 'Doe'
277
first_given = patient.get_by_path('name.0.given.0') # 'John'
278
city = patient.get_by_path('address.0.city') # 'Springfield'
279
street = patient.get_by_path('address.0.line.0') # '123 Main St'
280
281
# Safe access with defaults
282
phone = patient.get_by_path('telecom.0.value', 'No phone') # 'No phone'
283
284
print(f"Patient: {first_given} {family_name} from {city}")
285
```
286
287
### Resource References and Relationships
288
289
```python
290
async def reference_example():
291
client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')
292
293
# Create patient
294
patient = client.resource('Patient',
295
name=[{'family': 'Doe', 'given': ['John']}]
296
)
297
await patient.create()
298
299
# Create observation referencing the patient
300
observation = client.resource('Observation',
301
status='final',
302
code={
303
'coding': [{
304
'system': 'http://loinc.org',
305
'code': '55284-4',
306
'display': 'Blood pressure'
307
}]
308
},
309
subject=patient.to_reference(), # Convert to reference
310
valueQuantity={
311
'value': 120,
312
'unit': 'mmHg',
313
'system': 'http://unitsofmeasure.org',
314
'code': 'mm[Hg]'
315
}
316
)
317
await observation.create()
318
319
# Access reference properties
320
patient_ref = observation['subject']
321
print(f"Subject reference: {patient_ref.reference}")
322
print(f"Subject ID: {patient_ref.id}")
323
print(f"Subject type: {patient_ref.resource_type}")
324
```
325
326
### Resource Serialization
327
328
```python
329
async def serialization_example():
330
client = AsyncFHIRClient('https://hapi.fhir.org/baseR4')
331
332
patient = client.resource('Patient',
333
name=[{'family': 'Doe', 'given': ['John']}],
334
active=True
335
)
336
337
# Serialize for storage or transmission
338
patient_dict = patient.serialize()
339
340
# Convert to JSON string
341
import json
342
patient_json = json.dumps(patient_dict, indent=2)
343
print(patient_json)
344
345
# Load from dict
346
loaded_patient = client.resource('Patient', **patient_dict)
347
```