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
Python bindings for ArrayFire: A general purpose GPU library.

ArrayFire Python Bindings ArrayFire is a high performance library for parallel computing with an easy-to-use API. It enables users to write scientific

ArrayFire 402 Dec 20, 2022
Python wrapper for CoWin API's

Cowin Tracker Python API wrapper for CoWin, India's digital platform launched by the government to help citizens register themselves for the vaccinati

Saiprasad Balasubramanian 43 Jun 11, 2022
Name says it all/Instructions are in README file.

Discord-Webhook-Spammer Name says it all/Instructions are in README file. Setup 1. pip install discord-webhook ( In console, terminal or whatever you

Catto 1 Mar 21, 2022
A basic implementation of the Battlesnake API in Python

Getting started with Battlesnake and Python This is a basic implementation of the Battlesnake API in Python. It's a great starting point for anyone wa

Gaurav Batra 2 Dec 08, 2021
Token Manager written in Python

Discord-API-Token-Entrance Description This is a Token Manager that allows your token to enter your discord server, written in python. Packages Requir

Tootle 1 Apr 15, 2022
Asyncevents: a small library to help developers perform asynchronous event handling in Python

asyncevents - Asynchronous event handling for modern Python asyncevents is a small library to help developers perform asynchronous event handling in m

Mattia 5 Aug 07, 2022
Role Discord Members (by username) from File

Role Discord Members (by username) from File Bot Setup Navigate to https://discord.com/developers/applications Create a new application Navigate to th

Dylan Orrell 3 Jan 06, 2022
Widevine MPD Content Downloader & Decryptor

Widevine-DL Encrypted MPD Manifest Content Downloader + Decryptor (not a Widevine Key Extractor!) Requirements ffmpeg, yt-dlp, aria2, widevine-l3-decr

Vank0n (SJJeon) 170 Dec 30, 2022
Monetize your apps with KivAds using Google AdMob api.

KivAds(WIP) Monetize your apps with KivAds using Google AdMob api. KivAds uses the latest version of Google AdMob sdk(version 20.0.0). KivAds exposes

Guhan Sensam 16 Nov 05, 2022
Python client for the Echo Nest API

Pyechonest Tap into The Echo Nest's Musical Brain for the best music search, information, recommendations and remix tools on the web. Pyechonest is an

The Echo Nest 655 Dec 29, 2022
IBD Style Relative Strength Percentile Ranking of Stocks (i.e. 0-100 Score).

relative-strength IBD Style Relative Strength Percentile Ranking of Stocks (i.e. 0-100 Score). I also made a TradingView indicator, but it cannot give

57 Jan 06, 2023
Build better AWS infrastructure

Sceptre About Sceptre is a tool to drive AWS CloudFormation. It automates the mundane, repetitive and error-prone tasks, enabling you to concentrate o

sceptre 1.4k Jan 04, 2023
Instagram bot for promoting ROKA trainee soldier(just like me)'s consolation letters.

Instagram_bot (필자를 포함한) 모든 대한민국 훈련병들을 위한 인스타그램 인편지기입니다. Instagram bot for promoting ROKA trainee soldier(just like me)'s consolation letters. 들어가기 (Ge

Lee, Jongjun 2 Nov 21, 2021
GUI Pancakeswap V2 and Uniswap V3 trading client (and bot) MOST ADVANCE TRADING BOT SUPPORT WINDOWS LINUX MAC (BUY TOKEN ON LAUNCH)

GUI Pancakeswap 2 and Uniswap 3 SNIPER BOT 🏆 🥇 (MOST ADVANCE TRADING BOT SUPPORT WINDOWS LINUX MAC) (AUTO BUY TOKEN ON LAUNCH AFTER ADD LIQUIDITY) S

HYDRA 16 Dec 22, 2021
API para realizar parser de frases

NLP API Simple api to parse and apply some preprocessing steps in portuguses phrases (pt_BR) This api uses the great FastAPI and spaCy packages! Usage

⟠ Rodolfo De Nadai 1 Dec 28, 2021
This is a simple Python bot to identify sentiments in tweets

Twitter-Sentiment 👋 Hi There! 📱 This is a simple Python bot to identify sentiments in tweets 👨‍💻 This project was made for study, and pratice. You

Guilherme Silva 1 Oct 28, 2021
A plugin for modmail-bot for stealing,making ,etc emojis

EmojiPlugin for the Modmail-bot My first plugin .. its very Basic I will make more and better too Only 3 commands for now emojiadd-supports .jpg, .png

1 Dec 28, 2021
Crud-python-sqlite: used to manage telephone contacts through python and sqlite

crud-python-sqlite This program is used to manage telephone contacts through python and sqlite. Dependencicas python3 sqlite3 Installation Clone the r

Luis Negrón 0 Jan 24, 2022
SickNerd aims to slowly enumerate Google Dorks via the googlesearch API then requests found pages for metadata

CLI tool for making Google Dorking a passive recon experience. With the ability to fetch and filter dorks from GHDB.

Jake Wnuk 21 Jan 02, 2023
Full-featured Python interface for the Slack API

This repository is archived and will not receive any updates It's time to say goodbye. I'm archiving Slacker. It's been getting harder to find time to

Oktay Sancak 1.6k Dec 13, 2022