Wrapper for the Swiss Parliament API for Python

Overview

PyPI Version Build Status

swissparlpy

This module provides easy access to the data of the OData webservice of the Swiss parliament.

Table of Contents

Installation

swissparlpy is available on PyPI, so to install it simply use:

$ pip install swissparlpy

Usage

See the examples directory for more scripts.

Get tables and their variables

>>> import swissparlpy as spp
>>> spp.get_tables()[:5] # get first 5 tables
['MemberParty', 'Party', 'Person', 'PersonAddress', 'PersonCommunication']
>>> spp.get_variables('Party') # get variables of table `Party`
['ID', 'Language', 'PartyNumber', 'PartyName', 'StartDate', 'EndDate', 'Modified', 'PartyAbbreviation']

Get data of a table

>>> import swissparlpy as spp
>>> data = spp.get_data('Canton', Language='DE')
>>> data
<swissparlpy.client.SwissParlResponse object at 0x7f8e38baa610>
>>> data.count
26
>>> data[0]
{'ID': 2, 'Language': 'DE', 'CantonNumber': 2, 'CantonName': 'Bern', 'CantonAbbreviation': 'BE'}
>>> [d['CantonName'] for d in data]
['Bern', 'Neuenburg', 'Genf', 'Wallis', 'Uri', 'Schaffhausen', 'Jura', 'Basel-Stadt', 'St. Gallen', 'Obwalden', 'Appenzell A.-Rh.', 'Solothurn', 'Waadt', 'Zug', 'Aargau', 'Basel-Landschaft', 'Luzern', 'Thurgau', 'Freiburg', 'Appenzell I.-Rh.', 'Schwyz', 'Graubünden', 'Glarus', 'Tessin', 'Zürich', 'Nidwalden']

The return value of get_data is iterable, so you can easily loop over it. Or you can use indices to access elements, e.g. data[1] to get the second element, or data[-1] to get the last one.

Even slicing is supported, so you can do things like only iterate over the first 5 elements using

for rec in data[:5]:
   print(rec)

Use together with pandas

To create a pandas DataFrame from get_data simply pass the return value to the constructor:

>>> import swissparlpy as spp
>>> import pandas as pd
>>> parties = spp.get_data('Party', Language='DE')
>>> parties_df = pd.DataFrame(parties)
>>> parties_df
      ID Language  PartyNumber  ...                   EndDate                         Modified PartyAbbreviation
0     12       DE           12  ... 2000-01-01 00:00:00+00:00 2010-12-26 13:05:26.430000+00:00                SP
1     13       DE           13  ... 2000-01-01 00:00:00+00:00 2010-12-26 13:05:26.430000+00:00               SVP
2     14       DE           14  ... 2000-01-01 00:00:00+00:00 2010-12-26 13:05:26.430000+00:00               CVP
3     15       DE           15  ... 2000-01-01 00:00:00+00:00 2010-12-26 13:05:26.430000+00:00      FDP-Liberale
4     16       DE           16  ... 2000-01-01 00:00:00+00:00 2010-12-26 13:05:26.430000+00:00               LDP
..   ...      ...          ...  ...                       ...                              ...               ...
78  1582       DE         1582  ... 2000-01-01 00:00:00+00:00 2015-12-03 08:48:38.250000+00:00             BastA
79  1583       DE         1583  ... 2000-01-01 00:00:00+00:00 2019-03-07 17:24:15.013000+00:00              CVPO
80  1584       DE         1584  ... 2000-01-01 00:00:00+00:00 2019-11-08 17:28:43.947000+00:00                Al
81  1585       DE         1585  ... 2000-01-01 00:00:00+00:00 2019-11-08 17:41:39.513000+00:00               EàG
82  1586       DE         1586  ... 2000-01-01 00:00:00+00:00 2021-08-12 07:59:22.627000+00:00               M-E

[83 rows x 8 columns]

Substrings

If you want to query for substrings there are two main operators to use:

__startswith:

>>> import swissparlpy as spp
>>> persons = spp.get_data("Person", Language="DE", LastName__startswith='Bal')
>>> persons.count
12

__contains

>>> import swissparlpy as spp
>>> co2_business = spp.get_data("Business", Title__contains="CO2", Language = "DE")
>>> co2_business.count
265

You can suffix any field with those operators to query the data.

Large queries

Large queries (especially the tables Voting and Transcripts) may result in server-side errors (500 Internal Server Error). In these cases it is recommended to download the data in smaller batches, save the individual blocks and combine them after the download.

This is an example script to download all votes of the legislative period 50, session by session, and combine them afterwards in one DataFrame:

import swissparlpy as spp
import pandas as pd
import os

__location__ = os.path.realpath(os.getcwd())
path = os.path.join(__location__, "voting50")

# download votes of one session and save as pickled DataFrame
def save_votes_of_session(id, path):
    if not os.path.exists(path):
        os.mkdir(path)
    data = spp.get_data("Voting", Language="DE", IdSession=id)
    print(f"{data.count} rows loaded.")
    df = pd.DataFrame(data)
    pickle_path = os.path.join(path, f'{id}.pks')
    df.to_pickle(pickle_path)
    print(f"Saved pickle at {pickle_path}")


# get all session of the 50 legislative period
sessions50 = spp.get_data("Session", Language="DE", LegislativePeriodNumber=50)
sessions50.count

for session in sessions50:
    print(f"Loading session {session['ID']}")
    save_votes_of_session(session['ID'], path)

# Combine to one dataframe
df_voting50 = pd.concat([pd.read_pickle(os.path.join(path, x)) for x in os.listdir(path)])

Credits

This library is inspired by the R package swissparl of David Zumbach. Ralph Straumann initial asked about a Python version of swissparl on Twitter, which led to this project.

Release

To create a new release, follow these steps (please respect Semantic Versioning):

  1. Adapt the version number in swissparlpy/__init__.py
  2. Update the CHANGELOG with the version
  3. Create a pull request to merge develop into main (make sure the tests pass!)
  4. Create a new release/tag on GitHub (on the main branch)
  5. The publication on PyPI happens via GitHub Actions on every tagged commit
You might also like...
EpikCord.py - This is an API Wrapper for Discord's API for Python

EpikCord.py - This is an API Wrapper for Discord's API for Python! We've decided not to fork discord.py and start completely from scratch for a new, better structuring system!

A simple Python API wrapper for Cloudflare Stream's API.

python-cloudflare-stream A basic Python API wrapper for working with Cloudflare Stream. Arbington.com started off using Cloudflare Stream. We used the

Discord-Wrapper - Discord Websocket Wrapper in python

This does not currently work and is in development Discord Websocket Wrapper in

An API wrapper around the pythonanywhere's API.

pyaww An API wrapper around the pythonanywhere's API. The name stands for pythonanywherewrapper. 100% api coverage most of the codebase is documented

An API Wrapper for Gofile API

Gofile2 from gofile2 import Gofile g_a = Gofile() print(g_a.upload(file="/home/itz-fork/photo.png")) An API Wrapper for Gofile API. About API Gofile

A simple API wrapper for the Tenor API

Gifpy A simple API wrapper for the Tenor API Installation Python 3.9 or higher is recommended python3 -m pip install gifpy Clone repository: $ git cl

An API wrapper around Discord API.

NeoCord This project is work in progress not for production use. An asynchronous API wrapper around Discord API written in Python. Features Modern API

A wrapper for The Movie Database API v3 and v4 that only uses the read access token (not api key).

fulltmdb A wrapper for The Movie Database API v3 and v4 that only uses the read access token (not api key). Installation Use the package manager pip t

An API wrapper around the pythonanywhere's API.

pyaww An API wrapper around the pythonanywhere's API. The name stands for pythonanywherewrapper. 100% API coverage Most of the codebase is documented

Comments
  • Ein Datum wird bei bestimmten Sessionen nicht richtig geparst

    Ein Datum wird bei bestimmten Sessionen nicht richtig geparst

    Danke vielmals für das tolle Swissparlpy-Modul! Ich habe versucht, Dein Beispiel für Votes auf den Download von Reden (Table ’Transcript’) anzuwenden, bekomme aber ein Fehler beim Parsen eines Datums. Die Session 5002 (spp.get_data("Transcript", IdSession=5002)) geht interessanterweise, aber die Sessionen 5001 und 5003 nicht (z.B. spp.get_data("Transcript", IdSession=5001)), da bekomme ich jeweils den Fehler, dass strptime ein Datum nicht Parsen kann. Hier mein Code:

    import swissparlpy as spp
    import pandas as pd
    import os
    
    __location__ = os.path.realpath(os.getcwd())
    path2 = os.path.join(__location__, "transcripts50")
    
    # download transcripts of one session and save as pickled DataFrame
    def save_transcripts_of_session(id, path2):
        if not os.path.exists(path2):
            os.mkdir(path2)
        data = spp.get_data("Transcript", IdSession=id)
        print(f"{data.count} rows loaded.")
        df = pd.DataFrame(data)
        pickle_path = os.path.join(path2, f'{id}.pks')
        df.to_pickle(pickle_path)
        print(f"Saved pickle at {pickle_path}")
    
    save_transcripts_of_session(5001, path2)
    
    

    Hier die Fehlermeldung: Fehler_Transcripts.txt Mein Problem ist, dass nicht ersichtlich wird, welche Variable der Fehler betrifft und ob die Einträge mit diesem Datum schlicht ignoriert werden können?

    opened by bwueest 5
  • Added documentation for swissparAPY tables

    Added documentation for swissparAPY tables

    Provided some documentation using dbdiagram.io to have an explanation of the roles of the fields and tables as well as their relationships.

    Added

    docs folder containing the code and visualization for the documentation.

    Updated

    README.md to include the visualization as well as a link to the code.

    opened by peterbonnesoeur 2
  • Discrepancy between count and returned entities

    Discrepancy between count and returned entities

    Hello,

    Thank you for your work on the library !

    I think there might be an issue either from the parlement api or from the library. Basically the returned count is different from the number of entities. Here are the steps to reproduce:

    import swissparlpy as spp
    person = spp.get_data("Person")
    print(person.count)
    print(len(person.entities))
    

    Result:

    18170
    1000
    

    Any Idea why this is the case?

    Thanks!

    opened by Ahmedjjj 1
Releases(v0.2.1)
Owner
Stefan Oderbolz
Stefan Oderbolz
Simple Telegram webscrap bot

webscrap-bot Simple Telegram webscrap bot Configs TOKEN - Get bot token from @BotFather API_ID - From my.telegram.org API_HASH - From my.telegram.org

lokaman chendekar 10 Oct 21, 2022
Dumps to CSV all the resources in an organization's member accounts

AWS Org Inventory Dumps to CSV all the resources in an organization's member accounts. Set your environment's AWS_PROFILE and AWS_DEFAULT_REGION varia

Iain Samuel McLean Elder 2 Dec 24, 2021
Cryptocurrency Prices Telegram Bot For Python

Cryptocurrency Prices Telegram Bot How to Run Set your telegram bot token as environment variable TELEGRAM_BOT_TOKEN: export TELEGRAM_BOT_TOKEN=your_

Sina Nazem 3 Oct 31, 2022
🤖 A discord bot for Dota2 community

BOTA BOT-A is a free Discord Dota 2 bot which provides comprehensive Information of every Dota 2 characters and exciting features for the community. P

Bendang 23 Jun 29, 2022
GUI Pancakeswap2 and Uniswap3 trading client (and bot)

GUI Pancakeswap2 and Uniswap3 trading client (and bot) (MOST ADVANCE TRADING BOT SUPPORT WINDOWS LINUX MAC) (AUTO BUY TOKEN ON LUNCH AFTER ADD LIQUIDI

16 Dec 23, 2021
arweave-nft-uploader is a Python tool to improve the experience of uploading NFTs to the Arweave storage for use with the Metaplex Candy Machine.

arweave-nft-uploader arweave-nft-uploader is a Python tool to improve the experience of uploading NFTs to the Arweave storage for use with the Metaple

0xEnrico 84 Dec 26, 2022
Fetch tracking numbers of Amazon orders, for the ease of the logistics.

Amazon-Tracking-Number Fetch tracking numbers of Amazon orders, for the ease of the logistics. Read Me First (How to use this code): Get Amazon "Items

Tony Yao 1 Nov 02, 2021
A multipurpose Telegram Bot writen in Python for mirroring files

Deepak Clouds Mirror Deepak Clouds Torrent is a multipurpose Telegram Bot writen in Python for mirroring files on the Internet to our beloved Google D

MR.SHAGGY 0 Dec 19, 2021
Мои личные наработки по новому API Тинькофф. Не официально.

TinkoffNewAPI Мои личные наработки по новому API Тинькофф. Не официально. Официально по ссылке: https://github.com/Tinkoff/investAPI/ Выложено по прос

1 Jan 20, 2022
A repository of publicly verifiable token Sale contracts

Token-Sale-Plutus-Contract A repository of publicly verifiable token sale and royalty contracts. This will be the storage solution since it is easily

Logical Mechanism 29 Aug 18, 2022
Dados Públicos de CNPJ disponibilizados pela Receita Federal do Brasil

Dados Públicos CNPJ Fonte oficial da Receita Federal do Brasil, aqui. Layout dos arquivos, aqui. A Receita Federal do Brasil disponibiliza bases com o

Aphonso Henrique do Amaral Rafael 102 Dec 28, 2022
☄️ High performance, easy to use and feature-rich Solana SDK for Python.

Solathon is an high performance, easy to use and feature-rich Solana SDK for Python. Easy for beginners, powerful for real world applications.

Bolt 28 Oct 10, 2022
Connects to a local SenseCap M1 Helium Hotspot and pulls API Data.

sensecap_api_checker_HELIUM Connects to a local SenseCap M1 Helium Hotspot and pulls API Data.

Lorentz Factr 1 Nov 03, 2021
Notflix - Notion / Netflix and IMDb to organise your movie dates. Happy Valentine <3 from 0x1za

Welcome to notflix 👋 This is a project to help organise shows to watch with my

Mwiza Ed' Simbeye 3 Feb 15, 2022
Telegram bot that let's you flip a coin in a dialog

coin_flip Telegram bot that let's you flip a coin in a dialog Report issue · Request feature About Software development tool that lets you finally dec

Ivan Akostelov 2 Dec 12, 2021
A Discord bot that enables using breakout rooms on a server

Discord Breakout Room Bot This bot enables you to use breakout rooms on your Discord server! Note This bot was thrown together within a few hours, so

Till Müller 2 Nov 23, 2021
Policy and data administration, distribution, and real-time updates on top of Open Policy Agent

⚡ OPAL ⚡ Open Policy Administration Layer OPAL is an administration layer for Open Policy Agent (OPA), detecting changes to both policy and policy dat

8 Dec 07, 2022
Aula-API - a school system widely used in Denmark, as you can see and read about in the python file

Information : Hello, thank you for reading this first of all. This is a Aula-API

Binary.club 2 May 28, 2022
A Python 2.7/3.x module for Amcrest Cameras using the SDK HTTP API.

A Python 2.7/3.x module for Amcrest Cameras using the SDK HTTP API. Amcrest and Dahua devices share similar firmwares. Dahua Cameras and NVRs also work with this module.

Marcelo Moreira de Mello 176 Dec 21, 2022
A pypi packages finder telegram bot.

PyPi-Bot A pypi packages information finder telegram bot. Made with Python3 (C) @FayasNoushad Copyright permission under MIT License License - https:

Fayas Noushad 17 Oct 21, 2022