Metadata-Version: 2.4
Name: pydifact
Version: 0.2.1
Summary: Pydifact is a library that aims to provide complete support for reading and writing EDIFACT files. These file format, despite being old, is still a standard in many business cases. In Austria e.g., it is used for the transfer of medical reports between medical doctors.
Author-email: Christian González <christian.gonzalez@nerdocs.at>
License-Expression: MIT
Project-URL: Documentation, https://pydifact.readthedocs.io
Project-URL: Repository, https://github.com/nerdocs/pydifact
Project-URL: Issues, https://github.com/nerdocs/pydifact/issues
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: English
Classifier: Operating System :: MacOS :: MacOS X
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Provides-Extra: dev
Requires-Dist: pytest>=8.0.1; extra == "dev"
Requires-Dist: pytest-cov>=4.1.0; extra == "dev"
Requires-Dist: pytest-profiling>=1.7.0; extra == "dev"
Requires-Dist: keyring>=24.3.0; extra == "dev"
Requires-Dist: Sphinx>=7.2.0; extra == "dev"
Requires-Dist: setuptools>=69.1.0; extra == "dev"
Requires-Dist: wheel>=0.42.0; extra == "dev"
Requires-Dist: black>=25.1.0; extra == "dev"
Requires-Dist: sphinx-rtd-theme>=2.0.0; extra == "dev"
Requires-Dist: build; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: mypy>=1.15.0; extra == "dev"
Dynamic: license-file

# pydifact

A Python library to parse and serialize UN/EDIFACT interchanges.

## Preamble

This is a port of [metroplex-systems/edifact](https://github.com/metroplex-systems/edifact) to Python. Thanks here at the start to [Craig Duncan](https://github.com/duncan3dc) for this cool piece of software. Porting was like a breeze due to the high code quality there. All credits for the initial code here go to him, I just did the translation to Python(3), some "pythonifications" of the code and little improvements.

### Why another EDIFACT library?

Because I did not find a decent UN/EDIFACT library for Python, so I decided to port one of the available good PHP libraries to Python. Here is the result.

ATM this is a Work In Progress, the API is not stable yet.
Feel free to help.

## Install

As usual, use a virtualenv, and install via pip or pipenv:

```bash
pip install pydifact
```

However, it is not stable yet, so the pypi version, including documentation and code examples, could differ from the latest git code. If in doubt, use the git version:
```bash
git clone https://github.com/nerdocs/pydifact.git
cd pydifact
pip install -e .
```


## Usage

To read a full Interchange from a file or string, take the `Interchange` class and
iter over the messages and segments:

```python
from pydifact.segmentcollection import Interchange

interchange = Interchange.from_file("./tests/data/wikipedia.edi")
interchange = Interchange.from_str(
    "UNA:+,? '"
    "UNB+UNOC:1+1234+3333+200102:2212+42'"
    "UNH+42z42+PAORES:93:1:IA'"
    "MSG+1:45'"
    "IFT+3+XYZCOMPANY AVAILABILITY'"
    "ERC+A7V:1:AMD'"
    "UNT+5+42z42'UNZ+2+42'"
)
for message in interchange.get_messages():
    for segment in message.segments:
        print(f"Segment tag: {segment.tag}, content: {segment.elements}")
```

You may also want to iterate directly on segments :

```python
from pydifact.segmentcollection import Interchange

interchange = Interchange.from_str(
    "UNA:+,? '"
    "UNB+UNOC:1+1234+3333+200102:2212+42'"
    "UNH+42z42+PAORES:93:1:IA'"
    "MSG+1:45'"
    "IFT+3+XYZCOMPANY AVAILABILITY'"
    "ERC+A7V:1:AMD'"
    "UNT+5+42z42'UNZ+2+42'"
)

for segment in interchange.segments:
    print(f"Segment tag: {segment.tags}, content: {segment.elements}")
```

Or you can create an EDI interchange on the fly:

```python
from pydifact.segmentcollection import Interchange
from pydifact.segments import Segment

interchange = Interchange(syntax_identifier=("IBMA",1),
                          sender="MeMyselfAndIrene",
                          recipient="TheOtherOne",
                          control_reference="KLuzs7c6")
interchange.add_segment(Segment("QTY", ["12", "3"]))

print(interchange.serialize())
```

To include or override the Service String Advice segment (`UNA`), just specify it as a regular segment:

```python
interchange.add_segment(Segment("UNA", ":+.? '"))
```

You may also want to parse a « raw » segment bunch which is not an interchange:

```python
from pydifact.segmentcollection import RawSegmentCollection

collection = RawSegmentCollection.from_str("UNH+1+ORDERS:D:96A:UN:EAN008'")

for segment in collection.segments:
    print(f"Segment tag: {segment.tags}, content: {segment.elements}")
```


## Limitations

- No support of optional functional groups (`UNG`→`UNE`),

## Alternatives

In python ecosystem:

- [python-edifact](https://github.com/FriedrichK/python-edifact) - simpler, IMHO less clean code, less flexible. may be faster though (not tested). Seems unmaintained.
- [bots](https://github.com/bots-edi/bots) - huge, with webinterface (bots-monitor), webserver, bots-engine.
- [edicat](https://github.com/notpeter/edicat) - simple, only for separating lines/segments for CLI-piping.

## Development

### Setup

To develop pydifact, clone the repository and install the dev requirements:

```bash
make dev
# or
# pip install -e .[dev]
```

This installs all the python packages needed for development and testing.

### Code formatting

Format all python files using [black](https://black.readthedocs.io) before committing.

Happy coding, PR are more than welcome to make this library better, or to add a feature that matches your needs.
Nevertheless, don't forget adding tests for every aspect you add in code.

### Testing

pydifact uses [pytest](http://pytest.org) for testing. There is a shortcut in the Makefile for your convenience:

```bash
make test
```

This is recommended for faster testing.


There are some additional tests to check the performance of parsing huge files - you can include that tests by calling

```bash
make test-extended
```

## Credits
The official formats for UN/EDIFAT provided by UN Secretariat are raw text files located [here](http://www.unece.org/tradewelcome/un-centre-for-trade-facilitation-and-e-business-uncefact/outputs/standards/unedifact/directories/download.html) and html (.htm) files located [here](http://www.unece.org/tradewelcome/un-centre-for-trade-facilitation-and-e-business-uncefact/outputs/standards/unedifact/directories/2011-present.html), similarly for service codes as text and html files located at https://www.gefeg.com/jswg/.

There are many other helpful projects and people who made this possible:
* [untid-parser](https://github.com/php-edifact/untdid-parser) by [Stefano](https://github.com/sabas) - thanks for your help.

For a contributors' list, see [Contributors](https://github.com/nerdocs/pydifact/graphs/contributors).

## License

This library is licensed under the
*MIT* license, see the
[LICENSE file](LICENSE).
