vcon 0.3.0__tar.gz → 0.3.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
vcon-0.3.4/PKG-INFO ADDED
@@ -0,0 +1,577 @@
1
+ Metadata-Version: 2.1
2
+ Name: vcon
3
+ Version: 0.3.4
4
+ Summary: The vCon library
5
+ License: MIT
6
+ Author: Thomas McCarthy-Howe
7
+ Author-email: ghostofbasho@gmail.com
8
+ Requires-Python: >=3.8,<4.0
9
+ Classifier: License :: OSI Approved :: MIT License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.8
12
+ Classifier: Programming Language :: Python :: 3.9
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Requires-Dist: authlib (>=1.3.2,<2.0.0)
17
+ Requires-Dist: pydash (>=8.0.3,<9.0.0)
18
+ Requires-Dist: pytest (>=8.3.2,<9.0.0)
19
+ Requires-Dist: pytest-cov (>=5.0.0,<6.0.0)
20
+ Requires-Dist: pytest-mock (>=3.14.0,<4.0.0)
21
+ Requires-Dist: requests (>=2.32.3,<3.0.0)
22
+ Requires-Dist: uuid6 (>=2024.7.10,<2025.0.0)
23
+ Description-Content-Type: text/markdown
24
+
25
+ # vCon Python Library
26
+
27
+ This Python library provides a convenient way to work with vCon (Virtualized Conversation) objects. vCon is a standard for representing conversation data, including metadata, dialog, analysis, and attachments.
28
+
29
+ ## Features
30
+
31
+ - Create and manipulate vCon objects
32
+ - Add parties, dialogs, attachments, and analysis to vCons
33
+ - Sign and verify vCons using JWS (JSON Web Signature)
34
+ - Generate UUID8 identifiers
35
+ - Pack and unpack dialogs
36
+ - Add and retrieve tags
37
+
38
+ ## Installation
39
+
40
+ To install the vCon library, use pip:
41
+
42
+ ```
43
+ pip install vcon
44
+ ```
45
+
46
+ ## Usage
47
+ from vcon import Vcon
48
+ from vcon.party import Party
49
+ from vcon.dialog import Dialog
50
+ import json
51
+
52
+ # Create a new vCon
53
+ vcon = Vcon.build_new()
54
+
55
+ first_party = Party(name="Alice", tel="+1234567890")
56
+ vcon.add_party(first_party)
57
+ second_party = Party(name="Bob", tel="+0987654321")
58
+ vcon.add_party(second_party)
59
+
60
+ dialog = Dialog(start="2023-06-01T10:00:00Z",
61
+ parties=[0],
62
+ type="text",
63
+ body="Hello, world!")
64
+
65
+ vcon.add_dialog(dialog)
66
+
67
+
68
+ # Add an attachment
69
+ vcon.add_attachment(
70
+ body={"call_center": "yarmouth"},
71
+ type="routing"
72
+ )
73
+
74
+ # Add analysis
75
+ vcon.add_analysis(
76
+ type="sentiment",
77
+ dialog=[0],
78
+ vendor="AnalysisCompany",
79
+ body={"sentiment": "positive"}
80
+ )
81
+
82
+ # Add a tag
83
+ vcon.add_tag("importance", "high")
84
+
85
+ # Sign the vCon
86
+ private_key, public_key = Vcon.generate_key_pair()
87
+ vcon.sign(private_key)
88
+
89
+ # Verify the signature
90
+ is_valid = vcon.verify(public_key)
91
+
92
+ # Convert to JSON
93
+ vcon_json = vcon.to_json()
94
+
95
+ # Create a vCon from JSON
96
+ new_vcon = Vcon.build_from_json(vcon_json)
97
+
98
+ # Print the vCon
99
+ print(json.dumps(new_vcon.to_json(), indent=4))
100
+
101
+
102
+ ## API Reference
103
+
104
+ The vcon library provides functionality for working with vCon (Virtualized Conversation) objects.
105
+
106
+ ## Modules
107
+
108
+ ### vcon
109
+
110
+ The main module containing the Vcon class.
111
+
112
+ #### Classes
113
+
114
+ ##### Vcon
115
+
116
+ ```python
117
+ class Vcon(vcon_dict={})
118
+ ```
119
+
120
+ The main class for working with vCon objects.
121
+
122
+ - `vcon_dict`: A dictionary representing a vCon (default: empty dict)
123
+
124
+ ###### Class Methods
125
+
126
+ ```python
127
+ @classmethod
128
+ def build_from_json(json_string: str) -> Vcon
129
+ ```
130
+
131
+ Initialize a Vcon object from a JSON string.
132
+
133
+ - `json_string`: A JSON string representing a vCon
134
+ - Returns: A Vcon object
135
+
136
+ ```python
137
+ @classmethod
138
+ def build_new() -> Vcon
139
+ ```
140
+
141
+ Initialize a Vcon object with default values.
142
+
143
+ - Returns: A Vcon object
144
+
145
+ ###### Methods
146
+
147
+ ```python
148
+ def get_tag(tag_name) -> Optional[dict]
149
+ ```
150
+
151
+ Returns the value of a tag by name.
152
+
153
+ - `tag_name`: The name of the tag
154
+ - Returns: The value of the tag or None if not found
155
+
156
+ ```python
157
+ def add_tag(tag_name, tag_value) -> None
158
+ ```
159
+
160
+ Adds a tag to the vCon.
161
+
162
+ - `tag_name`: The name of the tag
163
+ - `tag_value`: The value of the tag
164
+
165
+ ```python
166
+ def find_attachment_by_type(type: str) -> Optional[dict]
167
+ ```
168
+
169
+ Finds an attachment by type.
170
+
171
+ - `type`: The type of the attachment
172
+ - Returns: The attachment or None if not found
173
+
174
+ ```python
175
+ def add_attachment(*, body: Union[dict, list, str], type: str, encoding="none") -> None
176
+ ```
177
+
178
+ Adds an attachment to the vCon.
179
+
180
+ - `body`: The body of the attachment
181
+ - `type`: The type of the attachment
182
+ - `encoding`: The encoding of the attachment body (default: "none")
183
+
184
+ ```python
185
+ def find_analysis_by_type(type) -> Any | None
186
+ ```
187
+
188
+ Finds an analysis by type.
189
+
190
+ - `type`: The type of the analysis
191
+ - Returns: The analysis or None if not found
192
+
193
+ ```python
194
+ def add_analysis(*, type: str, dialog: Union[list, int], vendor: str, body: Union[dict, list, str], encoding="none", extra={}) -> None
195
+ ```
196
+
197
+ Adds analysis data to the vCon.
198
+
199
+ - `type`: The type of the analysis
200
+ - `dialog`: The dialog(s) associated with the analysis
201
+ - `vendor`: The vendor of the analysis
202
+ - `body`: The body of the analysis
203
+ - `encoding`: The encoding of the body (default: "none")
204
+ - `extra`: Extra key-value pairs to include in the analysis
205
+
206
+ ```python
207
+ def add_party(party: Party) -> None
208
+ ```
209
+
210
+ Adds a party to the vCon.
211
+
212
+ - `party`: The party to add
213
+
214
+ ```python
215
+ def find_party_index(by: str, val: str) -> Optional[int]
216
+ ```
217
+
218
+ Find the index of a party in the vCon given a key-value pair.
219
+
220
+ - `by`: The key to look for
221
+ - `val`: The value to look for
222
+ - Returns: The index of the party if found, None otherwise
223
+
224
+ ```python
225
+ def find_dialog(by: str, val: str) -> Optional[dict]
226
+ ```
227
+
228
+ Find a dialog in the vCon given a key-value pair.
229
+
230
+ - `by`: The key to look for
231
+ - `val`: The value to look for
232
+ - Returns: The dialog if found, None otherwise
233
+
234
+ ```python
235
+ def add_dialog(dialog: dict) -> None
236
+ ```
237
+
238
+ Add a dialog to the vCon.
239
+
240
+ - `dialog`: The dialog to add
241
+
242
+ ```python
243
+ def to_json() -> str
244
+ ```
245
+
246
+ Serialize the vCon to a JSON string.
247
+
248
+ - Returns: A JSON string representation of the vCon
249
+
250
+ ```python
251
+ def to_dict() -> dict
252
+ ```
253
+
254
+ Serialize the vCon to a dictionary.
255
+
256
+ - Returns: A dictionary representation of the vCon
257
+
258
+ ```python
259
+ def dumps() -> str
260
+ ```
261
+
262
+ Alias for `to_json()`.
263
+
264
+ - Returns: A JSON string representation of the vCon
265
+
266
+ ```python
267
+ def sign(private_key) -> None
268
+ ```
269
+
270
+ Sign the vCon using JWS.
271
+
272
+ - `private_key`: The private key used for signing
273
+
274
+ ```python
275
+ def verify(public_key) -> bool
276
+ ```
277
+
278
+ Verify the JWS signature of the vCon.
279
+
280
+ - `public_key`: The public key used for verification
281
+ - Returns: True if the signature is valid, False otherwise
282
+
283
+ ```python
284
+ @classmethod
285
+ def generate_key_pair() -> tuple
286
+ ```
287
+
288
+ Generate a new RSA key pair for signing vCons.
289
+
290
+ - Returns: A tuple containing the private key and public key
291
+
292
+ ###### Properties
293
+
294
+ - `tags`: Returns the tags attachment.
295
+ - `parties`: Returns the list of parties.
296
+ - `dialog`: Returns the list of dialogs.
297
+ - `attachments`: Returns the list of attachments.
298
+ - `analysis`: Returns the list of analyses.
299
+ - `uuid`: Returns the UUID of the vCon.
300
+ - `vcon`: Returns the vCon version.
301
+ - `subject`: Returns the subject of the vCon.
302
+ - `created_at`: Returns the creation timestamp of the vCon.
303
+ - `updated_at`: Returns the last update timestamp of the vCon.
304
+ - `redacted`: Returns the redacted information of the vCon.
305
+ - `appended`: Returns the appended information of the vCon.
306
+ - `group`: Returns the group information of the vCon.
307
+ - `meta`: Returns the metadata of the vCon.
308
+
309
+ ### party
310
+
311
+ Module containing the Party class.
312
+
313
+ #### Classes
314
+
315
+ ##### Party
316
+
317
+ ```python
318
+ class Party(tel: Optional[str] = None, stir: Optional[str] = None, mailto: Optional[str] = None, name: Optional[str] = None, validation: Optional[str] = None, gmlpos: Optional[str] = None, civicaddress: Optional[CivicAddress] = None, uuid: Optional[str] = None, role: Optional[str] = None, contact_list: Optional[str] = None, meta: Optional[dict] = None)
319
+ ```
320
+
321
+ Represents a party in a vCon.
322
+
323
+ - `tel`: Telephone number of the party
324
+ - `stir`: STIR identifier of the party
325
+ - `mailto`: Email address of the party
326
+ - `name`: Display name of the party
327
+ - `validation`: Validation information of the party
328
+ - `gmlpos`: GML position of the party
329
+ - `civicaddress`: Civic address of the party
330
+ - `uuid`: UUID of the party
331
+ - `role`: Role of the party
332
+ - `contact_list`: Contact list of the party
333
+ - `meta`: Additional metadata for the party
334
+
335
+ ###### Methods
336
+
337
+ ```python
338
+ def to_dict() -> dict
339
+ ```
340
+
341
+ Returns a dictionary representation of the Party object.
342
+
343
+ - Returns: A dictionary containing the Party object's attributes
344
+
345
+ ##### PartyHistory
346
+
347
+ ```python
348
+ class PartyHistory(party: int, event: str, time: datetime)
349
+ ```
350
+
351
+ Represents the history of a party's participation in a dialog.
352
+
353
+ - `party`: Index of the party
354
+ - `event`: Event type (e.g. "join", "leave")
355
+ - `time`: Time of the event
356
+
357
+ ###### Methods
358
+
359
+ ```python
360
+ def to_dict() -> dict
361
+ ```
362
+
363
+ Returns a dictionary representation of the PartyHistory object.
364
+
365
+ - Returns: A dictionary containing the PartyHistory object's attributes
366
+
367
+ ### dialog
368
+
369
+ Module containing the Dialog class.
370
+
371
+ #### Classes
372
+
373
+ ##### Dialog
374
+
375
+ ```python
376
+ class Dialog(type: str, start: datetime, parties: List[int], originator: Optional[int] = None, mimetype: Optional[str] = None, filename: Optional[str] = None, body: Optional[str] = None, encoding: Optional[str] = None, url: Optional[str] = None, alg: Optional[str] = None, signature: Optional[str] = None, disposition: Optional[str] = None, party_history: Optional[List[PartyHistory]] = None, transferee: Optional[int] = None, transferor: Optional[int] = None, transfer_target: Optional[int] = None, original: Optional[int] = None, consultation: Optional[int] = None, target_dialog: Optional[int] = None, campaign: Optional[str] = None, interaction: Optional[str] = None, skill: Optional[str] = None, duration: Optional[float] = None)
377
+ ```
378
+
379
+ Represents a dialog in a vCon.
380
+
381
+ - `type`: The type of the dialog (e.g. "text", "audio", etc.)
382
+ - `start`: The start time of the dialog
383
+ - `parties`: The parties involved in the dialog
384
+ - `originator`: The party that originated the dialog
385
+ - `mimetype`: The MIME type of the dialog body
386
+ - `filename`: The filename of the dialog body
387
+ - `body`: The body of the dialog
388
+ - `encoding`: The encoding of the dialog body
389
+ - `url`: The URL of the dialog
390
+ - `alg`: The algorithm used to sign the dialog
391
+ - `signature`: The signature of the dialog
392
+ - `disposition`: The disposition of the dialog
393
+ - `party_history`: The history of parties involved in the dialog
394
+ - `transferee`: The party that the dialog was transferred to
395
+ - `transferor`: The party that transferred the dialog
396
+ - `transfer_target`: The target of the transfer
397
+ - `original`: The original dialog
398
+ - `consultation`: The consultation dialog
399
+ - `target_dialog`: The target dialog
400
+ - `campaign`: The campaign that the dialog is associated with
401
+ - `interaction`: The interaction that the dialog is associated with
402
+ - `skill`: The skill that the dialog is associated with
403
+ - `duration`: The duration of the dialog
404
+
405
+ ###### Methods
406
+
407
+ ```python
408
+ def to_dict() -> dict
409
+ ```
410
+
411
+ Returns a dictionary representation of the Dialog object.
412
+
413
+ - Returns: A dictionary containing the Dialog object's attributes
414
+
415
+ ```python
416
+ def add_external_data(url: str, filename: str, mimetype: str) -> None
417
+ ```
418
+
419
+ Add external data to the dialog.
420
+
421
+ - `url`: The URL of the external data
422
+ - `filename`: The filename of the external data
423
+ - `mimetype`: The MIME type of the external data
424
+
425
+ ```python
426
+ def add_inline_data(body: str, filename: str, mimetype: str) -> None
427
+ ```
428
+
429
+ Add inline data to the dialog.
430
+
431
+ - `body`: The body of the inline data
432
+ - `filename`: The filename of the inline data
433
+ - `mimetype`: The MIME type of the inline data
434
+
435
+ ```python
436
+ def is_external_data() -> bool
437
+ ```
438
+
439
+ Check if the dialog is an external data dialog.
440
+
441
+ - Returns: True if the dialog is an external data dialog, False otherwise
442
+
443
+ ```python
444
+ def is_inline_data() -> bool
445
+ ```
446
+
447
+ Check if the dialog is an inline data dialog.
448
+
449
+ - Returns: True if the dialog is an inline data dialog, False otherwise
450
+
451
+ ```python
452
+ def is_text() -> bool
453
+ ```
454
+
455
+ Check if the dialog is a text dialog.
456
+
457
+ - Returns: True if the dialog is a text dialog, False otherwise
458
+
459
+ ```python
460
+ def is_audio() -> bool
461
+ ```
462
+
463
+ Check if the dialog is an audio dialog.
464
+
465
+ - Returns: True if the dialog is an audio dialog, False otherwise
466
+
467
+ ```python
468
+ def is_video() -> bool
469
+ ```
470
+
471
+ Check if the dialog is a video dialog.
472
+
473
+ - Returns: True if the dialog is a video dialog, False otherwise
474
+
475
+ ```python
476
+ def is_email() -> bool
477
+ ```
478
+
479
+ Check if the dialog is an email dialog.
480
+
481
+ - Returns: True if the dialog is an email dialog, False otherwise
482
+
483
+ ```python
484
+ def is_external_data_changed() -> bool
485
+ ```
486
+
487
+ Check if the external data dialog contents have changed.
488
+
489
+ - Returns: True if the contents have changed, False otherwise
490
+
491
+ ```python
492
+ def to_inline_data() -> None
493
+ ```
494
+
495
+ Convert the dialog from an external data dialog to an inline data dialog.
496
+
497
+ ### civic_address
498
+
499
+ Module containing the CivicAddress class.
500
+
501
+ #### Classes
502
+
503
+ ##### CivicAddress
504
+
505
+ ```python
506
+ class CivicAddress(country: Optional[str] = None, a1: Optional[str] = None, a2: Optional[str] = None, a3: Optional[str] = None, a4: Optional[str] = None, a5: Optional[str] = None, a6: Optional[str] = None, prd: Optional[str] = None, pod: Optional[str] = None, sts: Optional[str] = None, hno: Optional[str] = None, hns: Optional[str] = None, lmk: Optional[str] = None, loc: Optional[str] = None, flr: Optional[str] = None, nam: Optional[str] = None, pc: Optional[str] = None)
507
+ ```
508
+
509
+ Represents a civic address.
510
+
511
+ - `country`: Country code (ISO 3166-1 alpha-2)
512
+ - `a1`: Administrative area 1 (e.g. state or province)
513
+ - `a2`: Administrative area 2 (e.g. county or municipality)
514
+ - `a3`: Administrative area 3 (e.g. city or town)
515
+ - `a4`: Administrative area 4 (e.g. neighborhood or district)
516
+ - `a5`: Administrative area 5 (e.g. postal code)
517
+ - `a6`: Administrative area 6 (e.g. building or floor)
518
+ - `prd`: Premier (e.g. department or suite number)
519
+ - `pod`: Post office box identifier
520
+ - `sts`: Street name
521
+ - `hno`: House number
522
+ - `hns`: House name
523
+ - `lmk`: Landmark name
524
+ - `loc`: Location name
525
+ - `flr`: Floor
526
+ - `nam`: Name of the location
527
+ - `pc`: Postal code
528
+
529
+ ###### Methods
530
+
531
+ ```python
532
+ def to_dict() -> dict[str, Optional[str]]
533
+ ```
534
+
535
+ Convert the CivicAddress object to a dictionary.
536
+
537
+ - Returns: A dictionary of the object's attributes
538
+
539
+ This Markdown version of the API documentation should be easier to read and integrate into various documentation systems or README files. It provides a comprehensive overview of the classes, methods, and attributes available in the vcon library.
540
+
541
+
542
+ ## Contributing
543
+
544
+ Contributions to the vCon library are welcome! Please submit pull requests or open issues on the GitHub repository.
545
+
546
+ ## License
547
+
548
+ This project is licensed under the MIT License:
549
+
550
+ MIT License
551
+
552
+ Copyright (c) 2023 Thomas McCarthy-Howe
553
+
554
+ Permission is hereby granted, free of charge, to any person obtaining a copy
555
+ of this software and associated documentation files (the "Software"), to deal
556
+ in the Software without restriction, including without limitation the rights
557
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
558
+ copies of the Software, and to permit persons to whom the Software is
559
+ furnished to do so, subject to the following conditions:
560
+
561
+ The above copyright notice and this permission notice shall be included in all
562
+ copies or substantial portions of the Software.
563
+
564
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
565
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
566
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
567
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
568
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
569
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
570
+ SOFTWARE.
571
+
572
+ ## Contact
573
+
574
+ For questions or support, please contact:
575
+
576
+ Thomas McCarthy-Howe
577
+ Email: ghostofbasho@gmail.com