bundestag-api


Namebundestag-api JSON
Version 1.3.0 PyPI version JSON
download
home_pagehttps://github.com/jschibberges/Bundestag-API
SummaryPython wrapper for the official Bundestag-API
upload_time2025-10-20 19:44:04
maintainerNone
docs_urlNone
authorJulian Schibberges
requires_python>=3.7.0
licenseMIT
keywords bundestag api parliament germany german politics political data legislation legislative federal documents drucksache plenarprotokoll politicians government democracy deutscher-bundestag parliamentary open-data civic-tech transparency political-science policy bundesrepublik deutschland
VCS
bugtrack_url
requirements openpyxl pandas requests
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Bundestag API

[![Upload Python Package](https://github.com/jschibberges/Bundestag-API/actions/workflows/python-publish.yml/badge.svg)](https://github.com/jschibberges/Bundestag-API/actions/workflows/python-publish.yml)
[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)

A beginner-friendly Python wrapper for accessing German Federal Parliament (Bundestag) data. This package simplifies querying parliamentary documents, procedures, plenary protocols, and member information through the official Bundestag API.

Perfect for data scientists, researchers, and political analysts who want to analyze German parliamentary data without dealing with complex API calls.

## What You Can Do

- **Analyze Parliamentary Documents**: Access bills, reports, and official documents
- **Track Legislative Processes**: Follow how laws move through parliament
- **Study Voting Patterns**: Examine plenary protocols and activities
- **Research Politicians**: Get information about current and former members of parliament
- **Time Series Analysis**: Filter data by date ranges for trend analysis

## Quick Start

### Installation

```bash
pip install bundestag_api
```

### Your First Query

```python
import bundestag_api

# Create a connection (uses free public API key)
bt = bundestag_api.btaConnection()

# Get recent documents
documents = bt.search_document(limit=5, date_start="2024-01-01")

# Print document titles
for doc in documents:
    print(f"{doc['drucksachetyp']}: {doc['titel']}")
```

## Core Concepts

The Bundestag API provides access to 6 main data types:

| Data Type | Description | Use Cases |
|-----------|-------------|-----------|
| **Documents** (`drucksache`) | Bills, reports, proposals | Policy analysis, text mining |
| **Procedures** (`vorgang`) | Legislative processes | Tracking law development |
| **Activities** (`aktivitaet`) | Parliamentary actions | Voting behavior analysis |
| **Persons** (`person`) | MPs and officials | Political network analysis |
| **Plenary Protocols** (`plenarprotokoll`) | Session transcripts | Speech analysis, debate tracking |
| **Procedure Positions** (`vorgangsposition`) | Steps in processes | Process flow analysis |

## Common Use Cases for Data Scientists

### 1. Document Analysis

```python
# Get all documents from a specific time period
documents = bt.search_document(
    date_start="2024-01-01",
    date_end="2024-03-31",
    limit=100
)

# Get full text for analysis
doc_with_text = bt.search_document(
    fid=[12345],  # specific document ID
    fulltext=True
)
```

### 2. Tracking Legislative Processes

```python
# Find procedures by topic
procedures = bt.search_procedure(
    descriptor=["Climate", "Energy"],  # AND search
    limit=50
)

# Get detailed procedure information
procedure_details = bt.get_procedure(btid=12345)
```

### 3. Analyzing Parliamentary Speeches

```python
# Get plenary protocols with full text
protocols = bt.search_plenaryprotocol(
    date_start="2024-01-01",
    fulltext=True,
    limit=10
)
```

### 4. Member Analysis

```python
# Search for members of the Bundestag
members = bt.search_person(limit=100)

# Get detailed information about a specific person
member_details = bt.get_person(btid=12345)
```

## Working with Data

### Return Formats

The package supports multiple return formats to fit your workflow:

```python
# JSON format (default) - good for general analysis
data_json = bt.search_document(return_format="json")

# Python objects - good for object-oriented programming
data_objects = bt.search_document(return_format="object")

# Pandas DataFrame - perfect for data analysis
data_df = bt.search_document(return_format="pandas")
```

### Filtering Data

All search functions support common filters:

```python
documents = bt.search_document(
    date_start="2024-01-01",      # Start date (YYYY-MM-DD)
    date_end="2024-12-31",        # End date (YYYY-MM-DD)  
    institution="BT",             # BT=Bundestag, BR=Bundesrat
    drucksache_type="Antrag",     # Specific 'Drucksache' types
    title=["Climate", "Energy"],  # Keywords in title (OR search)
    limit=100                     # Maximum results
)
```

### Handling Large Datasets

```python
# Get all documents (automatically handles pagination)
all_documents = bt.search_document(
    date_start="2024-01-01",
    limit=1000  # Will make multiple API calls as needed
)

# Process data in chunks for memory efficiency
for i in range(0, len(all_documents), 100):
    chunk = all_documents[i:i+100]
    # Process your chunk here
    process_documents(chunk)
```

### Parallel Processing

⚠️ **Important Rate Limit Information**

The Bundestag API has a **maximum of 25 concurrent requests** limit. When using parallel processing (threading, multiprocessing, asyncio), you must respect this limit to avoid triggering bot protection.

#### API Key Considerations

**Generic API Key (default)**
- Shared potentially by all users globally
- More likely to hit rate limits

**Personal API Key** (recommended for production)
- Dedicated quota for your application
- Better performance and reliability
- Get your key at [dip.bundestag.de](https://dip.bundestag.de/)

#### Bot Protection Errors

If you encounter `ConnectionError: Bot protection detected (Enodia challenge)`, this means:
- Too many concurrent requests (>25)
- Too many requests per second
- The shared generic API key is overloaded

**Solutions:**
1. Reduce `max_workers` (try 5 or less)
2. Add `time.sleep()` delays between requests
3. Use a personal API key
4. Process data in smaller batches

## Data Structure Examples

### Document Structure
```python
{
    "id": 264030,
    "titel": "Climate Protection Act Amendment",
    "drucksachetyp": "Gesetzentwurf",
    "datum": "2024-01-15",
    "urheber": ["Federal Government"],
    "fundstelle": {
        "pdf_url": "https://...",
        "dokumentnummer": "20/1234"
    }
}
```

### Person Structure
```python
{
    "id": 12345,
    "vorname": "Angela",
    "nachname": "Merkel", 
    "titel": "Dr.",
    "person_roles": [{
        "funktion": "MdB",
        "fraktion": "CDU/CSU"
    }]
}
```

## API Authentication

The package includes a public API key that's valid until May 31, 2026. For production use or higher rate limits, request your personal API key from [parlamentsdokumentation@bundestag.de](mailto:parlamentsdokumentation@bundestag.de).

```python
# Using personal API key
bt = bundestag_api.btaConnection(apikey="your_api_key_here")
```

## Best Practices for Data Scientists

### 1. Start Small
```python
# Test with small datasets first
test_data = bt.search_document(limit=10)
print(f"Retrieved {len(test_data)} documents")
```

### 2. Use Appropriate Limits
```python
# Default limit is 100, increase for larger analyses
large_dataset = bt.search_document(limit=1000)
```

### 3. Handle Errors Gracefully
```python
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("bundestag_api")

# The package will log warnings and errors automatically
```

### 4. Combine with Data Analysis Libraries
```python
import pandas as pd
import numpy as np
from collections import Counter

# Get data as pandas DataFrame
df = bt.search_document(return_format="pandas", limit=500)

# Analyze document types
doc_types = Counter(df['drucksachetyp'])
print(doc_types.most_common(5))

# Time series analysis
df['datum'] = pd.to_datetime(df['datum'])
monthly_counts = df.groupby(df['datum'].dt.to_period('M')).size()
```

## Complete API Reference

### Search Functions
- `search_document(**filters)` - Find documents
- `search_procedure(**filters)` - Find legislative procedures  
- `search_activity(**filters)` - Find parliamentary activities
- `search_person(**filters)` - Find parliamentarians
- `search_plenaryprotocol(**filters)` - Find session protocols
- `search_procedureposition(**filters)` - Find procedure steps

### Get Functions (by ID)
- `get_document(btid, **options)` - Get specific documents
- `get_procedure(btid, **options)` - Get specific procedures
- `get_activity(btid, **options)` - Get specific activities  
- `get_person(btid, **options)` - Get specific persons
- `get_plenaryprotocol(btid, **options)` - Get specific protocols
- `get_procedureposition(btid, **options)` - Get specific procedure steps

## Common Issues & Solutions

**Memory issues with large datasets?**
- Use smaller `limit` values and process in chunks
- Use `return_format="pandas"` for better memory efficiency

**Getting empty results?**
- Check date formats (YYYY-MM-DD)
- Verify institution codes (BT, BR, BV, EK)
- Start with broader searches, then add filters

**Need full document text?**
- Set `fulltext=True` for documents and protocols
- Note: Full text significantly increases response size

## Contributing

Contributions are welcome! Please check the [GitHub repository](https://github.com/jschibberges/Bundestag-API) for current issues and development guidelines.

## License

This project is licensed under the MIT License. See the LICENSE file for details.

## Support

- GitHub Issues: [Report bugs or request features](https://github.com/jschibberges/Bundestag-API/issues)
- Official API Documentation: [Bundestag.de API](https://dip.bundestag.de/über-dip/hilfe/api)
- Email for API keys: [parlamentsdokumentation@bundestag.de](mailto:parlamentsdokumentation@bundestag.de)

---

*Made for data scientists who want to analyze German parliamentary data without the complexity of raw API calls.*

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/jschibberges/Bundestag-API",
    "name": "bundestag-api",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7.0",
    "maintainer_email": null,
    "keywords": "bundestag, api, parliament, germany, german, politics, political, data, legislation, legislative, federal, documents, drucksache, plenarprotokoll, politicians, government, democracy, deutscher-bundestag, parliamentary, open-data, civic-tech, transparency, political-science, policy, bundesrepublik, deutschland",
    "author": "Julian Schibberges",
    "author_email": "Julian Schibberges <julian@schibberges.de>",
    "download_url": "https://files.pythonhosted.org/packages/6b/5d/846ba72d1ed04b00095ac3b0cd78784434f40adc3f9200c3b7dec0ac4c1e/bundestag_api-1.3.0.tar.gz",
    "platform": null,
    "description": "# Bundestag API\n\n[![Upload Python Package](https://github.com/jschibberges/Bundestag-API/actions/workflows/python-publish.yml/badge.svg)](https://github.com/jschibberges/Bundestag-API/actions/workflows/python-publish.yml)\n[![Python 3.7+](https://img.shields.io/badge/python-3.7+-blue.svg)](https://www.python.org/downloads/)\n\nA beginner-friendly Python wrapper for accessing German Federal Parliament (Bundestag) data. This package simplifies querying parliamentary documents, procedures, plenary protocols, and member information through the official Bundestag API.\n\nPerfect for data scientists, researchers, and political analysts who want to analyze German parliamentary data without dealing with complex API calls.\n\n## What You Can Do\n\n- **Analyze Parliamentary Documents**: Access bills, reports, and official documents\n- **Track Legislative Processes**: Follow how laws move through parliament\n- **Study Voting Patterns**: Examine plenary protocols and activities\n- **Research Politicians**: Get information about current and former members of parliament\n- **Time Series Analysis**: Filter data by date ranges for trend analysis\n\n## Quick Start\n\n### Installation\n\n```bash\npip install bundestag_api\n```\n\n### Your First Query\n\n```python\nimport bundestag_api\n\n# Create a connection (uses free public API key)\nbt = bundestag_api.btaConnection()\n\n# Get recent documents\ndocuments = bt.search_document(limit=5, date_start=\"2024-01-01\")\n\n# Print document titles\nfor doc in documents:\n    print(f\"{doc['drucksachetyp']}: {doc['titel']}\")\n```\n\n## Core Concepts\n\nThe Bundestag API provides access to 6 main data types:\n\n| Data Type | Description | Use Cases |\n|-----------|-------------|-----------|\n| **Documents** (`drucksache`) | Bills, reports, proposals | Policy analysis, text mining |\n| **Procedures** (`vorgang`) | Legislative processes | Tracking law development |\n| **Activities** (`aktivitaet`) | Parliamentary actions | Voting behavior analysis |\n| **Persons** (`person`) | MPs and officials | Political network analysis |\n| **Plenary Protocols** (`plenarprotokoll`) | Session transcripts | Speech analysis, debate tracking |\n| **Procedure Positions** (`vorgangsposition`) | Steps in processes | Process flow analysis |\n\n## Common Use Cases for Data Scientists\n\n### 1. Document Analysis\n\n```python\n# Get all documents from a specific time period\ndocuments = bt.search_document(\n    date_start=\"2024-01-01\",\n    date_end=\"2024-03-31\",\n    limit=100\n)\n\n# Get full text for analysis\ndoc_with_text = bt.search_document(\n    fid=[12345],  # specific document ID\n    fulltext=True\n)\n```\n\n### 2. Tracking Legislative Processes\n\n```python\n# Find procedures by topic\nprocedures = bt.search_procedure(\n    descriptor=[\"Climate\", \"Energy\"],  # AND search\n    limit=50\n)\n\n# Get detailed procedure information\nprocedure_details = bt.get_procedure(btid=12345)\n```\n\n### 3. Analyzing Parliamentary Speeches\n\n```python\n# Get plenary protocols with full text\nprotocols = bt.search_plenaryprotocol(\n    date_start=\"2024-01-01\",\n    fulltext=True,\n    limit=10\n)\n```\n\n### 4. Member Analysis\n\n```python\n# Search for members of the Bundestag\nmembers = bt.search_person(limit=100)\n\n# Get detailed information about a specific person\nmember_details = bt.get_person(btid=12345)\n```\n\n## Working with Data\n\n### Return Formats\n\nThe package supports multiple return formats to fit your workflow:\n\n```python\n# JSON format (default) - good for general analysis\ndata_json = bt.search_document(return_format=\"json\")\n\n# Python objects - good for object-oriented programming\ndata_objects = bt.search_document(return_format=\"object\")\n\n# Pandas DataFrame - perfect for data analysis\ndata_df = bt.search_document(return_format=\"pandas\")\n```\n\n### Filtering Data\n\nAll search functions support common filters:\n\n```python\ndocuments = bt.search_document(\n    date_start=\"2024-01-01\",      # Start date (YYYY-MM-DD)\n    date_end=\"2024-12-31\",        # End date (YYYY-MM-DD)  \n    institution=\"BT\",             # BT=Bundestag, BR=Bundesrat\n    drucksache_type=\"Antrag\",     # Specific 'Drucksache' types\n    title=[\"Climate\", \"Energy\"],  # Keywords in title (OR search)\n    limit=100                     # Maximum results\n)\n```\n\n### Handling Large Datasets\n\n```python\n# Get all documents (automatically handles pagination)\nall_documents = bt.search_document(\n    date_start=\"2024-01-01\",\n    limit=1000  # Will make multiple API calls as needed\n)\n\n# Process data in chunks for memory efficiency\nfor i in range(0, len(all_documents), 100):\n    chunk = all_documents[i:i+100]\n    # Process your chunk here\n    process_documents(chunk)\n```\n\n### Parallel Processing\n\n\u26a0\ufe0f **Important Rate Limit Information**\n\nThe Bundestag API has a **maximum of 25 concurrent requests** limit. When using parallel processing (threading, multiprocessing, asyncio), you must respect this limit to avoid triggering bot protection.\n\n#### API Key Considerations\n\n**Generic API Key (default)**\n- Shared potentially by all users globally\n- More likely to hit rate limits\n\n**Personal API Key** (recommended for production)\n- Dedicated quota for your application\n- Better performance and reliability\n- Get your key at [dip.bundestag.de](https://dip.bundestag.de/)\n\n#### Bot Protection Errors\n\nIf you encounter `ConnectionError: Bot protection detected (Enodia challenge)`, this means:\n- Too many concurrent requests (>25)\n- Too many requests per second\n- The shared generic API key is overloaded\n\n**Solutions:**\n1. Reduce `max_workers` (try 5 or less)\n2. Add `time.sleep()` delays between requests\n3. Use a personal API key\n4. Process data in smaller batches\n\n## Data Structure Examples\n\n### Document Structure\n```python\n{\n    \"id\": 264030,\n    \"titel\": \"Climate Protection Act Amendment\",\n    \"drucksachetyp\": \"Gesetzentwurf\",\n    \"datum\": \"2024-01-15\",\n    \"urheber\": [\"Federal Government\"],\n    \"fundstelle\": {\n        \"pdf_url\": \"https://...\",\n        \"dokumentnummer\": \"20/1234\"\n    }\n}\n```\n\n### Person Structure\n```python\n{\n    \"id\": 12345,\n    \"vorname\": \"Angela\",\n    \"nachname\": \"Merkel\", \n    \"titel\": \"Dr.\",\n    \"person_roles\": [{\n        \"funktion\": \"MdB\",\n        \"fraktion\": \"CDU/CSU\"\n    }]\n}\n```\n\n## API Authentication\n\nThe package includes a public API key that's valid until May 31, 2026. For production use or higher rate limits, request your personal API key from [parlamentsdokumentation@bundestag.de](mailto:parlamentsdokumentation@bundestag.de).\n\n```python\n# Using personal API key\nbt = bundestag_api.btaConnection(apikey=\"your_api_key_here\")\n```\n\n## Best Practices for Data Scientists\n\n### 1. Start Small\n```python\n# Test with small datasets first\ntest_data = bt.search_document(limit=10)\nprint(f\"Retrieved {len(test_data)} documents\")\n```\n\n### 2. Use Appropriate Limits\n```python\n# Default limit is 100, increase for larger analyses\nlarge_dataset = bt.search_document(limit=1000)\n```\n\n### 3. Handle Errors Gracefully\n```python\nimport logging\n\nlogging.basicConfig(level=logging.INFO)\nlogger = logging.getLogger(\"bundestag_api\")\n\n# The package will log warnings and errors automatically\n```\n\n### 4. Combine with Data Analysis Libraries\n```python\nimport pandas as pd\nimport numpy as np\nfrom collections import Counter\n\n# Get data as pandas DataFrame\ndf = bt.search_document(return_format=\"pandas\", limit=500)\n\n# Analyze document types\ndoc_types = Counter(df['drucksachetyp'])\nprint(doc_types.most_common(5))\n\n# Time series analysis\ndf['datum'] = pd.to_datetime(df['datum'])\nmonthly_counts = df.groupby(df['datum'].dt.to_period('M')).size()\n```\n\n## Complete API Reference\n\n### Search Functions\n- `search_document(**filters)` - Find documents\n- `search_procedure(**filters)` - Find legislative procedures  \n- `search_activity(**filters)` - Find parliamentary activities\n- `search_person(**filters)` - Find parliamentarians\n- `search_plenaryprotocol(**filters)` - Find session protocols\n- `search_procedureposition(**filters)` - Find procedure steps\n\n### Get Functions (by ID)\n- `get_document(btid, **options)` - Get specific documents\n- `get_procedure(btid, **options)` - Get specific procedures\n- `get_activity(btid, **options)` - Get specific activities  \n- `get_person(btid, **options)` - Get specific persons\n- `get_plenaryprotocol(btid, **options)` - Get specific protocols\n- `get_procedureposition(btid, **options)` - Get specific procedure steps\n\n## Common Issues & Solutions\n\n**Memory issues with large datasets?**\n- Use smaller `limit` values and process in chunks\n- Use `return_format=\"pandas\"` for better memory efficiency\n\n**Getting empty results?**\n- Check date formats (YYYY-MM-DD)\n- Verify institution codes (BT, BR, BV, EK)\n- Start with broader searches, then add filters\n\n**Need full document text?**\n- Set `fulltext=True` for documents and protocols\n- Note: Full text significantly increases response size\n\n## Contributing\n\nContributions are welcome! Please check the [GitHub repository](https://github.com/jschibberges/Bundestag-API) for current issues and development guidelines.\n\n## License\n\nThis project is licensed under the MIT License. See the LICENSE file for details.\n\n## Support\n\n- GitHub Issues: [Report bugs or request features](https://github.com/jschibberges/Bundestag-API/issues)\n- Official API Documentation: [Bundestag.de API](https://dip.bundestag.de/\u00fcber-dip/hilfe/api)\n- Email for API keys: [parlamentsdokumentation@bundestag.de](mailto:parlamentsdokumentation@bundestag.de)\n\n---\n\n*Made for data scientists who want to analyze German parliamentary data without the complexity of raw API calls.*\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Python wrapper for the official Bundestag-API",
    "version": "1.3.0",
    "project_urls": {
        "Homepage": "https://github.com/jschibberges/Bundestag-API",
        "Issues": "https://github.com/jschibberges/Bundestag-API/issues",
        "Repository": "https://github.com/jschibberges/Bundestag-API"
    },
    "split_keywords": [
        "bundestag",
        " api",
        " parliament",
        " germany",
        " german",
        " politics",
        " political",
        " data",
        " legislation",
        " legislative",
        " federal",
        " documents",
        " drucksache",
        " plenarprotokoll",
        " politicians",
        " government",
        " democracy",
        " deutscher-bundestag",
        " parliamentary",
        " open-data",
        " civic-tech",
        " transparency",
        " political-science",
        " policy",
        " bundesrepublik",
        " deutschland"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5676038ac85b1ad6599a7cf735ba7cf3c752769b6af55ba7d62667c14d35fd00",
                "md5": "e7458d703ce88eff3e10556c9bea882c",
                "sha256": "141d002b8773d801ea56391dba088fcea5ee577b3d5feca7c298e56e65c5dc61"
            },
            "downloads": -1,
            "filename": "bundestag_api-1.3.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e7458d703ce88eff3e10556c9bea882c",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.7.0",
            "size": 18754,
            "upload_time": "2025-10-20T19:44:03",
            "upload_time_iso_8601": "2025-10-20T19:44:03.437634Z",
            "url": "https://files.pythonhosted.org/packages/56/76/038ac85b1ad6599a7cf735ba7cf3c752769b6af55ba7d62667c14d35fd00/bundestag_api-1.3.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6b5d846ba72d1ed04b00095ac3b0cd78784434f40adc3f9200c3b7dec0ac4c1e",
                "md5": "d9a75476e73730fb05178557aee10a50",
                "sha256": "f89fa94312a68414b3fb125c89f8469b9b85e8dfa14bf7a3ee620e2ae2df0677"
            },
            "downloads": -1,
            "filename": "bundestag_api-1.3.0.tar.gz",
            "has_sig": false,
            "md5_digest": "d9a75476e73730fb05178557aee10a50",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7.0",
            "size": 30265,
            "upload_time": "2025-10-20T19:44:04",
            "upload_time_iso_8601": "2025-10-20T19:44:04.672031Z",
            "url": "https://files.pythonhosted.org/packages/6b/5d/846ba72d1ed04b00095ac3b0cd78784434f40adc3f9200c3b7dec0ac4c1e/bundestag_api-1.3.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-20 19:44:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "jschibberges",
    "github_project": "Bundestag-API",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "openpyxl",
            "specs": [
                [
                    ">",
                    "3.0.0"
                ]
            ]
        },
        {
            "name": "pandas",
            "specs": [
                [
                    ">",
                    "1.2.0"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    ">",
                    "2.0.0"
                ]
            ]
        }
    ],
    "lcname": "bundestag-api"
}
        
Elapsed time: 1.39986s