Metadata-Version: 2.4
Name: okfn-iati
Version: 0.2.0
Summary: A Python library for working with IATI XML data according to the IATI 2.03 standard
Author-email: Open Knowledge Foundation <info@okfn.org>
Project-URL: Homepage, https://github.com/okfn/okfn_iati
Project-URL: Issues, https://github.com/okfn/okfn_iati/issues
Project-URL: Documentation, https://github.com/okfn/okfn_iati
Project-URL: Source Code, https://github.com/okfn/okfn_iati
Keywords: iati,xml,development,aid,transparency
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: lxml>=4.9.0
Provides-Extra: dev
Requires-Dist: lxml>=4.9.0; extra == "dev"
Requires-Dist: build>=0.8.0; extra == "dev"
Requires-Dist: twine>=4.0.0; extra == "dev"
Dynamic: license-file

[![Python Tests](https://github.com/okfn/okfn_iati/workflows/Python%20IATI%20Tests/badge.svg)](https://github.com/okfn/okfn_iati/actions)

# OKFN IATI XML Handler

A Python library for working with IATI XML data according to the IATI 2.03 standard.

## Features

- Data models that represent IATI XML elements with validation
- XML generator to create valid IATI XML from Python objects
- Support for IATI 2.03 standard
- Enums for standardized code lists
- Data validation to ensure compliance with the standard

## Installation

```bash
pip install okfn-iati
```

## Usage

### Creating an IATI Activity

```python
from okfn_iati import (
    # Main models
    Activity, Narrative, OrganizationRef, ParticipatingOrg, ActivityDate,
    Location, LocationIdentifier, DocumentLink,
    Budget, Transaction, IatiActivities,

    # Enums - use these constants instead of strings
    ActivityStatus, ActivityDateType, TransactionType, BudgetType, BudgetStatus,
    OrganisationRole, OrganisationType, LocationID, DocumentCategory,
    SectorCategory,

    # Generator
    IatiXmlGenerator
)

# Define reporting organization identifier (following IATI standard format)
reporting_org_id = "XM-DAC-12345"

# Create an IATI Activity
activity = Activity(
    # The activity identifier should begin with the reporting org identifier 
    # followed by a hyphen and a unique string: {org-id}-{activity-unique-id}
    iati_identifier=f"{reporting_org_id}-PROJECT001",
    reporting_org=OrganizationRef(
        ref=reporting_org_id,  # Must match the prefix of the activity identifier
        type=OrganisationType.GOVERNMENT.value,
        narratives=[Narrative(text="Example Organization")]
    ),
    title=[Narrative(text="Example Project")],
    description=[{
        "type": "1", 
        "narratives": [
            Narrative(text="This is an example project description")
        ]
    }],
    activity_status=ActivityStatus.IMPLEMENTATION,
    activity_dates=[
        ActivityDate(
            type=ActivityDateType.PLANNED_START,
            iso_date="2023-01-01",
            narratives=[Narrative(text="Planned start date")]
        ),
        ActivityDate(
            type=ActivityDateType.ACTUAL_START,
            iso_date="2023-01-15"
        )
    ],
    participating_orgs=[
        ParticipatingOrg(
            role=OrganisationRole.FUNDING,
            ref="XM-EXAMPLE-FUNDER",
            type=OrganisationType.GOVERNMENT.value,
            narratives=[Narrative(text="Example Funding Organization")]
        ),
        ParticipatingOrg(
            role=OrganisationRole.IMPLEMENTING,
            ref="XM-EXAMPLE-IMPL",
            narratives=[Narrative(text="Example Implementing Organization")]
        )
    ],
    # Required: recipient country or region
    recipient_countries=[
        {
            "code": "KE",
            "percentage": 100,
            "narratives": [Narrative(text="Kenya")]
        }
    ],
    locations=[
        Location(
            location_id=LocationIdentifier(
                vocabulary=LocationID.GEONAMES,
                code="1234567"
            ),
            name=[Narrative(text="Example Location")]
        )
    ],
    # Required: sector information
    sectors=[
        {
            "code": SectorCategory.EDUCATION_GENERAL.value,  # "11110"
            "vocabulary": "1",  # DAC vocabulary
            "percentage": 100
        }
    ],
    budgets=[
        Budget(
            type=BudgetType.ORIGINAL,
            status=BudgetStatus.INDICATIVE,
            period_start="2023-01-01",
            period_end="2023-12-31",
            value=100000.00,
            currency="USD",
            value_date="2023-01-01"  # Added required value_date
        )
    ],
    transactions=[
        Transaction(
            type=TransactionType.DISBURSEMENT,
            date="2023-03-15",
            value=50000.00,
            currency="USD",
            value_date="2023-03-15"  # Added required value_date
        )
    ],
    document_links=[
        DocumentLink(
            url="https://example.org/docs/report.pdf",
            format="application/pdf",
            title=[Narrative(text="Project Report")],
            categories=[DocumentCategory.OBJECTIVES]
        )
    ],
    default_currency="USD",
)

# Create an IATI Activities container
iati_activities = IatiActivities(
    version="2.03",
    activities=[activity]
)

# Generate XML
generator = IatiXmlGenerator()
xml_string = generator.generate_iati_activities_xml(iati_activities)

# Save to file
generator.save_to_file(iati_activities, "example_activity.xml")
```

## Validation with IATI Validator

The XML generated by this library follows the IATI schema and ruleset requirements. To validate your XML:

1. Generate your XML file using this library
2. Upload it to the [IATI Validator](https://validator.iatistandard.org/)
3. Check that it passes both schema validation and IATI ruleset validation

You can validate IATI XML using the built-in `IatiValidator` class:

```python
from okfn_iati import IatiValidator

# Create a validator
validator = IatiValidator()

# Validate XML string
with open("example_activity.xml", "r") as f:
    xml_string = f.read()
    is_valid, errors = validator.validate(xml_string)
    
    if is_valid:
        print("XML is valid!")
    else:
        print("XML validation errors:")
        for schema_error in errors['schema_errors']:
            print(f"  Schema error: {schema_error}")
        for ruleset_error in errors['ruleset_errors']:
            print(f"  Ruleset error: {ruleset_error}")
```

## Start your IATI project

You can start by creating a CSV file and this library will process it to generate valid IATI XML files.  
Read the docs in [englsh](/docs/data_requirements.md) or [spanish](/docs/data_requirements.es.md) to learn how to do it.  
