dzero-python


Namedzero-python JSON
Version 1.0.2 PyPI version JSON
download
home_pagehttps://github.com/tylerwinn/dzero-python
SummaryNCPDP Telecommunications Standard Version D.0 Message parser and serializer
upload_time2025-07-22 18:14:57
maintainerNone
docs_urlNone
authorPython Port of DZero
requires_python>=3.7
licenseNone
keywords ncpdp healthcare pharmacy telecommunications d0 parser serializer
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # DZero Python

A robust and easy-to-use Python implementation of the NCPDP Telecommunications Standard Version D.0 Message **parser** and **serializer**.

Ported from the original Ruby implementation battle-tested at [Instacart](https://www.instacart.com/opensource).

## Installation

```bash
pip install dzero-python
```

## Features

- ✅ Complete field mapping for all **26** D.0 Segment types.
  - Access field values by simple names instead of 2-character identifiers (ex: `claim_segment['fill_number']` instead of `claim_segment['D3']`)
- ✅ Parse D.0 Requests or Responses with ease.
  - ex: `Request.parse(your_raw_string)`
- ✅ Build D.0 Requests or Responses programmatically.
  - ex: `Request(...)` (see [Building](#building) below)
- ✅ Supports multiple transaction groups
  - ex: `request.transaction_groups[2].claim_segment`
- ✅ Serialize a D.0 message to JSON
  - ex: `request.to_json()`

## Usage

### Parsing and Manipulating

#### Parsing

```python
from dzero_python import Request

request = Request.parse(raw_message_string)
```

The above snippet will return a new instance of `Request`.

#### Reading the header

```python
print(request.header)
# => {
#   'bin_number': '999999',
#   'version': 'D0', 
#   'transaction_code': 'B1',
#   'processor_control_number': '',
#   'transaction_count': '1',
#   'service_provider_id_qualifier': '01',
#   'service_provider_id': '1111111111',
#   'date_of_service': '20181106',
#   'software': ''
# }
```

#### Reading a single segment

```python
request.transmission_group.patient_segment
# => <PatientSegment instance>

request.transmission_group.insurance_segment  
# => <InsuranceSegment instance>

request.transaction_groups[0].claim_segment
# => <ClaimSegment instance>

request.transaction_groups[2].claim_segment
# => <ClaimSegment instance>
```

#### Reading a field in a segment

Fields of a segment can be accessed via dictionary-style access, which takes either a symbol or a string.

```python
segment = request.transaction_groups[0].claim_segment
# => <ClaimSegment instance>

segment['segment_identification']
# => "07"

segment['AM'] 
# => "07"

segment['quantity_dispensed']
# => "2000"

segment['E7']
# => "2000"
```

#### Modifying a field in a segment

Fields of a segment can be modified via dictionary-style access. If a segment or field does not yet exist when it is accessed, it will be created and added to the message.

```python
segment = request.transaction_groups[0].claim_segment

segment['quantity_dispensed']
# => "2000"

segment['quantity_dispensed'] = "9990"
# => "9990"

segment['E7']
# => "9990"

segment['E7'] = "5555" 
# => "5555"

segment['quantity_dispensed']
# => "5555"
```

#### Serializing to JSON

`Request`, `Response`, `TransmissionGroup`, `TransactionGroup`, and `Segment` all have **`to_json`** methods.

```python
request.to_json()
```

**`to_json`** takes two options:
- **`readable`** - if this is True, symbols will be used for the fields of a segment, instead of the field identifiers.
- **`key_group_by_segment_sym`** - if this is True, groups will be objects instead of arrays of objects. A group object will be keyed by the segment identifiers it contains.

### Building

For messages with a single transaction group, you can pass segments in with the **`segments`** argument. DZero will automatically filter the segments into the correct locations (either the **`transmission_group`** or the first **`transaction_group`**)

```python
from dzero_python import Request
from dzero_python.segments import PatientSegment

request = Request(
    header={
        'bin_number': '999999',
        'version': 'D0',
        'transaction_code': 'B1', 
        'processor_control_number': '',
        'transaction_count': '1',
        'service_provider_id_qualifier': '01',
        'service_provider_id': '1111111111',
        'date_of_service': '20181106',
        'software': ''
    },
    segments=[
        PatientSegment({
            'patient_first_name': 'AUSTIN',
            'patient_last_name': 'PIVARNIK', 
            'patient_phone_number': '5555555555'
        })
    ]
)
```

For more control over the structure of the message, you can manually construct the `transmission_group` and the `transaction_groups`.

```python
from dzero_python import Response
from dzero_python.transmissions.groups import TransmissionGroup, TransactionGroup  
from dzero_python.segments import ResponseMessageSegment, ResponseStatusSegment

response = Response(
    header={
        'version': 'D0',
        'transaction_code': 'B1',
        'transaction_count': '1',
        'header_response_status': 'A',
        'service_provider_id_qualifier': '01', 
        'service_provider_id': '1111111111',
        'date_of_service': '20181106'
    },
    transmission_group=TransmissionGroup(
        segments=[
            ResponseMessageSegment({
                'message': 'TEST MESSAGE'
            })
        ]
    ),
    transaction_groups=[
        TransactionGroup(
            segments=[
                ResponseStatusSegment({
                    'response_status': 'C'
                })
            ]
        ),
        TransactionGroup(
            segments=[
                ResponseStatusSegment({
                    'response_status': 'R'  
                })
            ]
        )
    ]
)
```

### Stringifying a message

To render an instance of `Request` or `Response` into a D.0 string, simply call `to_s()` on the instance.

```python
request.to_s()
# => "999999D0B1          1011111111111     20181106          \u001E\u001CAM01\u001CCAAUSTIN\u001CCBPIVARNIK\u001CCQ5555555555"
```

### Serializing a message to JSON

```python
request.to_json(readable=True, key_group_by_segment_sym=True)
# => {
#   "header": {
#     "bin_number": "999999",
#     "version": "D0", 
#     "transaction_code": "B1",
#     "processor_control_number": "",
#     "transaction_count": "1",
#     "service_provider_id_qualifier": "01",
#     "service_provider_id": "9999999999",
#     "date_of_service": "11282018", 
#     "software": ""
#   },
#   "transmission_group": {
#     "patient": {
#       "segment_identification": "01",
#       "patient_first_name": "AUSTIN",
#       "patient_last_name": "PIVARNIK",
#       "patient_street_address": "50 BEALE ST",
#       "patient_city": "SAN FRANCISCO", 
#       "patient_state_or_province": "CA",
#       "patient_zip_postal_code": "94105",
#       "patient_phone_number": "5555555555"
#     }
#   },
#   "transaction_groups": [
#     {
#       "claim": {
#         "segment_identification": "07",
#         "prescription_reference_number_qualifier": "1",
#         "prescription_reference_number": "9999999999",
#         "product_service_id_qualifier": "03", 
#         "product_service_id": "99999999999",
#         "quantity_dispensed": "2000",
#         "fill_number": "0",
#         "days_supply": "1", 
#         "compound_code": "1",
#         "dispense_as_written_product_selection_code": "0",
#         "date_prescription_written": "20181025",
#         "number_of_refills_authorized": "99",
#         "prescription_origin_code": "1",
#         "unit_of_measure": "EA",
#         "level_of_service": "0",
#         "patient_assignment_indicator": "Y",
#         "pharmacy_service_type": "1"
#       },
#       "pricing": {
#         "segment_identification": "11",
#         "ingredient_cost_submitted": "A",
#         "dispensing_fee_submitted": "{",
#         "patient_paid_amount_submitted": "{", 
#         "percentage_sales_tax_rate_submitted": "1750{",
#         "usual_and_customary_charge": "A",
#         "gross_amount_due": "A",
#         "basis_of_cost_determination": "01"
#       }
#     }
#   ]
# }
```

## Development

This project is a Python port of the Ruby DZero library. It maintains API compatibility where possible while following Python conventions.

## License

MIT License - see LICENSE file for details.

## Contributing

Bug reports and pull requests are welcome on GitHub.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/tylerwinn/dzero-python",
    "name": "dzero-python",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "ncpdp healthcare pharmacy telecommunications d0 parser serializer",
    "author": "Python Port of DZero",
    "author_email": null,
    "download_url": "https://files.pythonhosted.org/packages/de/46/58d29ae92312a35af43b85a478b6ae49d78e5906f1e524c9ddb13dc7e4f3/dzero_python-1.0.2.tar.gz",
    "platform": null,
    "description": "# DZero Python\r\n\r\nA robust and easy-to-use Python implementation of the NCPDP Telecommunications Standard Version D.0 Message **parser** and **serializer**.\r\n\r\nPorted from the original Ruby implementation battle-tested at [Instacart](https://www.instacart.com/opensource).\r\n\r\n## Installation\r\n\r\n```bash\r\npip install dzero-python\r\n```\r\n\r\n## Features\r\n\r\n- \u2705 Complete field mapping for all **26** D.0 Segment types.\r\n  - Access field values by simple names instead of 2-character identifiers (ex: `claim_segment['fill_number']` instead of `claim_segment['D3']`)\r\n- \u2705 Parse D.0 Requests or Responses with ease.\r\n  - ex: `Request.parse(your_raw_string)`\r\n- \u2705 Build D.0 Requests or Responses programmatically.\r\n  - ex: `Request(...)` (see [Building](#building) below)\r\n- \u2705 Supports multiple transaction groups\r\n  - ex: `request.transaction_groups[2].claim_segment`\r\n- \u2705 Serialize a D.0 message to JSON\r\n  - ex: `request.to_json()`\r\n\r\n## Usage\r\n\r\n### Parsing and Manipulating\r\n\r\n#### Parsing\r\n\r\n```python\r\nfrom dzero_python import Request\r\n\r\nrequest = Request.parse(raw_message_string)\r\n```\r\n\r\nThe above snippet will return a new instance of `Request`.\r\n\r\n#### Reading the header\r\n\r\n```python\r\nprint(request.header)\r\n# => {\r\n#   'bin_number': '999999',\r\n#   'version': 'D0', \r\n#   'transaction_code': 'B1',\r\n#   'processor_control_number': '',\r\n#   'transaction_count': '1',\r\n#   'service_provider_id_qualifier': '01',\r\n#   'service_provider_id': '1111111111',\r\n#   'date_of_service': '20181106',\r\n#   'software': ''\r\n# }\r\n```\r\n\r\n#### Reading a single segment\r\n\r\n```python\r\nrequest.transmission_group.patient_segment\r\n# => <PatientSegment instance>\r\n\r\nrequest.transmission_group.insurance_segment  \r\n# => <InsuranceSegment instance>\r\n\r\nrequest.transaction_groups[0].claim_segment\r\n# => <ClaimSegment instance>\r\n\r\nrequest.transaction_groups[2].claim_segment\r\n# => <ClaimSegment instance>\r\n```\r\n\r\n#### Reading a field in a segment\r\n\r\nFields of a segment can be accessed via dictionary-style access, which takes either a symbol or a string.\r\n\r\n```python\r\nsegment = request.transaction_groups[0].claim_segment\r\n# => <ClaimSegment instance>\r\n\r\nsegment['segment_identification']\r\n# => \"07\"\r\n\r\nsegment['AM'] \r\n# => \"07\"\r\n\r\nsegment['quantity_dispensed']\r\n# => \"2000\"\r\n\r\nsegment['E7']\r\n# => \"2000\"\r\n```\r\n\r\n#### Modifying a field in a segment\r\n\r\nFields of a segment can be modified via dictionary-style access. If a segment or field does not yet exist when it is accessed, it will be created and added to the message.\r\n\r\n```python\r\nsegment = request.transaction_groups[0].claim_segment\r\n\r\nsegment['quantity_dispensed']\r\n# => \"2000\"\r\n\r\nsegment['quantity_dispensed'] = \"9990\"\r\n# => \"9990\"\r\n\r\nsegment['E7']\r\n# => \"9990\"\r\n\r\nsegment['E7'] = \"5555\" \r\n# => \"5555\"\r\n\r\nsegment['quantity_dispensed']\r\n# => \"5555\"\r\n```\r\n\r\n#### Serializing to JSON\r\n\r\n`Request`, `Response`, `TransmissionGroup`, `TransactionGroup`, and `Segment` all have **`to_json`** methods.\r\n\r\n```python\r\nrequest.to_json()\r\n```\r\n\r\n**`to_json`** takes two options:\r\n- **`readable`** - if this is True, symbols will be used for the fields of a segment, instead of the field identifiers.\r\n- **`key_group_by_segment_sym`** - if this is True, groups will be objects instead of arrays of objects. A group object will be keyed by the segment identifiers it contains.\r\n\r\n### Building\r\n\r\nFor messages with a single transaction group, you can pass segments in with the **`segments`** argument. DZero will automatically filter the segments into the correct locations (either the **`transmission_group`** or the first **`transaction_group`**)\r\n\r\n```python\r\nfrom dzero_python import Request\r\nfrom dzero_python.segments import PatientSegment\r\n\r\nrequest = Request(\r\n    header={\r\n        'bin_number': '999999',\r\n        'version': 'D0',\r\n        'transaction_code': 'B1', \r\n        'processor_control_number': '',\r\n        'transaction_count': '1',\r\n        'service_provider_id_qualifier': '01',\r\n        'service_provider_id': '1111111111',\r\n        'date_of_service': '20181106',\r\n        'software': ''\r\n    },\r\n    segments=[\r\n        PatientSegment({\r\n            'patient_first_name': 'AUSTIN',\r\n            'patient_last_name': 'PIVARNIK', \r\n            'patient_phone_number': '5555555555'\r\n        })\r\n    ]\r\n)\r\n```\r\n\r\nFor more control over the structure of the message, you can manually construct the `transmission_group` and the `transaction_groups`.\r\n\r\n```python\r\nfrom dzero_python import Response\r\nfrom dzero_python.transmissions.groups import TransmissionGroup, TransactionGroup  \r\nfrom dzero_python.segments import ResponseMessageSegment, ResponseStatusSegment\r\n\r\nresponse = Response(\r\n    header={\r\n        'version': 'D0',\r\n        'transaction_code': 'B1',\r\n        'transaction_count': '1',\r\n        'header_response_status': 'A',\r\n        'service_provider_id_qualifier': '01', \r\n        'service_provider_id': '1111111111',\r\n        'date_of_service': '20181106'\r\n    },\r\n    transmission_group=TransmissionGroup(\r\n        segments=[\r\n            ResponseMessageSegment({\r\n                'message': 'TEST MESSAGE'\r\n            })\r\n        ]\r\n    ),\r\n    transaction_groups=[\r\n        TransactionGroup(\r\n            segments=[\r\n                ResponseStatusSegment({\r\n                    'response_status': 'C'\r\n                })\r\n            ]\r\n        ),\r\n        TransactionGroup(\r\n            segments=[\r\n                ResponseStatusSegment({\r\n                    'response_status': 'R'  \r\n                })\r\n            ]\r\n        )\r\n    ]\r\n)\r\n```\r\n\r\n### Stringifying a message\r\n\r\nTo render an instance of `Request` or `Response` into a D.0 string, simply call `to_s()` on the instance.\r\n\r\n```python\r\nrequest.to_s()\r\n# => \"999999D0B1          1011111111111     20181106          \\u001E\\u001CAM01\\u001CCAAUSTIN\\u001CCBPIVARNIK\\u001CCQ5555555555\"\r\n```\r\n\r\n### Serializing a message to JSON\r\n\r\n```python\r\nrequest.to_json(readable=True, key_group_by_segment_sym=True)\r\n# => {\r\n#   \"header\": {\r\n#     \"bin_number\": \"999999\",\r\n#     \"version\": \"D0\", \r\n#     \"transaction_code\": \"B1\",\r\n#     \"processor_control_number\": \"\",\r\n#     \"transaction_count\": \"1\",\r\n#     \"service_provider_id_qualifier\": \"01\",\r\n#     \"service_provider_id\": \"9999999999\",\r\n#     \"date_of_service\": \"11282018\", \r\n#     \"software\": \"\"\r\n#   },\r\n#   \"transmission_group\": {\r\n#     \"patient\": {\r\n#       \"segment_identification\": \"01\",\r\n#       \"patient_first_name\": \"AUSTIN\",\r\n#       \"patient_last_name\": \"PIVARNIK\",\r\n#       \"patient_street_address\": \"50 BEALE ST\",\r\n#       \"patient_city\": \"SAN FRANCISCO\", \r\n#       \"patient_state_or_province\": \"CA\",\r\n#       \"patient_zip_postal_code\": \"94105\",\r\n#       \"patient_phone_number\": \"5555555555\"\r\n#     }\r\n#   },\r\n#   \"transaction_groups\": [\r\n#     {\r\n#       \"claim\": {\r\n#         \"segment_identification\": \"07\",\r\n#         \"prescription_reference_number_qualifier\": \"1\",\r\n#         \"prescription_reference_number\": \"9999999999\",\r\n#         \"product_service_id_qualifier\": \"03\", \r\n#         \"product_service_id\": \"99999999999\",\r\n#         \"quantity_dispensed\": \"2000\",\r\n#         \"fill_number\": \"0\",\r\n#         \"days_supply\": \"1\", \r\n#         \"compound_code\": \"1\",\r\n#         \"dispense_as_written_product_selection_code\": \"0\",\r\n#         \"date_prescription_written\": \"20181025\",\r\n#         \"number_of_refills_authorized\": \"99\",\r\n#         \"prescription_origin_code\": \"1\",\r\n#         \"unit_of_measure\": \"EA\",\r\n#         \"level_of_service\": \"0\",\r\n#         \"patient_assignment_indicator\": \"Y\",\r\n#         \"pharmacy_service_type\": \"1\"\r\n#       },\r\n#       \"pricing\": {\r\n#         \"segment_identification\": \"11\",\r\n#         \"ingredient_cost_submitted\": \"A\",\r\n#         \"dispensing_fee_submitted\": \"{\",\r\n#         \"patient_paid_amount_submitted\": \"{\", \r\n#         \"percentage_sales_tax_rate_submitted\": \"1750{\",\r\n#         \"usual_and_customary_charge\": \"A\",\r\n#         \"gross_amount_due\": \"A\",\r\n#         \"basis_of_cost_determination\": \"01\"\r\n#       }\r\n#     }\r\n#   ]\r\n# }\r\n```\r\n\r\n## Development\r\n\r\nThis project is a Python port of the Ruby DZero library. It maintains API compatibility where possible while following Python conventions.\r\n\r\n## License\r\n\r\nMIT License - see LICENSE file for details.\r\n\r\n## Contributing\r\n\r\nBug reports and pull requests are welcome on GitHub.\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "NCPDP Telecommunications Standard Version D.0 Message parser and serializer",
    "version": "1.0.2",
    "project_urls": {
        "Homepage": "https://github.com/tylerwinn/dzero-python"
    },
    "split_keywords": [
        "ncpdp",
        "healthcare",
        "pharmacy",
        "telecommunications",
        "d0",
        "parser",
        "serializer"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "bd71b239455d99fc167f56dd71327b543d59094c25b011cf0dd70b40d4679eec",
                "md5": "20fe660d07937527d538fbaf53fe2bad",
                "sha256": "d804b0b1890a1b70dd28f483332f4278adc0b692e00cba9e841e2cfe5909824f"
            },
            "downloads": -1,
            "filename": "dzero_python-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "20fe660d07937527d538fbaf53fe2bad",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7",
            "size": 37381,
            "upload_time": "2025-07-22T18:14:56",
            "upload_time_iso_8601": "2025-07-22T18:14:56.572876Z",
            "url": "https://files.pythonhosted.org/packages/bd/71/b239455d99fc167f56dd71327b543d59094c25b011cf0dd70b40d4679eec/dzero_python-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "de4658d29ae92312a35af43b85a478b6ae49d78e5906f1e524c9ddb13dc7e4f3",
                "md5": "071b667d2b896361fbdf734cd793f490",
                "sha256": "c2c005402a69c6b4543ad2df6b45e9e484dfbd8eded4396c27d3ce55fba7ccc7"
            },
            "downloads": -1,
            "filename": "dzero_python-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "071b667d2b896361fbdf734cd793f490",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 22935,
            "upload_time": "2025-07-22T18:14:57",
            "upload_time_iso_8601": "2025-07-22T18:14:57.727615Z",
            "url": "https://files.pythonhosted.org/packages/de/46/58d29ae92312a35af43b85a478b6ae49d78e5906f1e524c9ddb13dc7e4f3/dzero_python-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-22 18:14:57",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "tylerwinn",
    "github_project": "dzero-python",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "dzero-python"
}
        
Elapsed time: 0.46211s