Skip to main content

Abstraction layer for interacting with Microsoft Dataverse in Python. Supports batch operations!

Project description

dataverse-api

Ruff Build Status codecov

The dataverse-api package is an abstraction layer developed for allowing simple interaction with Microsoft Dataverse Web API.

Table of Contents

Description

The main goal of this project was to enable some use-cases against Dataverse that I wanted to explore for a work assignment, while getting some experience in programming and testing out different ways of setting up the codebase.

The functionality I have built into this Dataverse wrapper constitutes the functionality I have wanted to explore myself.

Most important is to enable creating, upserting, updating and deleting rows of data into Dataverse tables using common data structures, and implementing choices on how these requests are to be formed. For example, when creating new rows, the user can choose between individual POST requests per row, combining data into batch requests against the $batch endpoint, or even to use the CreateMultiple Dataverse action.

The framework is written in Python 3.11, seeing as this runtime is available in the current release of Azure Functions.

Getting started

Usage is fairly simple - authentication must be handled by the user. The DataverseClient simply accepts an already authorized requests.Session with which to handle API requests.

I suggest using msal and msal-requests-auth for authenticating the Session. The examples below include this way of implementing auth:

import os

from msal import ConfidentialClientApplication
from msal_requests_auth.auth import ClientCredentialAuth
from requests import Session

from dataverse_api import DataverseClient

# Prepare Auth
app_id = os.getenv("app_id")
secret = os.getenv("client_secret")
environment_url = os.getenv("environment_url")
authority_url = os.getenv("authority_url")
app_reg = ConfidentialClientApplication(
    client_id=app_id,
    client_credential=secret,
    authority=authority_url,
)
auth = ClientCredentialAuth(
    client=app_reg,
    scopes=[environment_url + "/.default"]
)

# Prepare Session
session = Session()
session.auth = auth

# Instantiate DataverseClient
client = DataverseClient(session, environment_url)

# Instantiate interface to Entity
entity = client.entity(logical_name="organization")

# Read data!
entity.read(select=["name"])

Development environment

poetry is used for managing dependencies. To develop dataverse-api, follow the below steps to set up your local environment:

  1. Install poetry if you haven't already.

  2. Clone repository:

    $ git clone git@github.com:MarcusRisanger/dataverse-api.git
    
  3. Move into the newly created local repository:

    $ cd dataverse-api
    
  4. Create virtual environment and install dependencies:

    $ poetry install
    

Code requirements

All code must pass ruff style checks to be merged. It is recommended to install pre-commit hooks to ensure this locally before commiting code:

$ poetry run pre-commit install

Each public method, class and module should have docstrings. Docstrings are written in the Numpy style.

Testing

To produce Coverage reports, run the following commands:

$ poetry run coverage run -m pytest
$ poetry run coverage xml

To Do:

Usage

DataverseClient

Initialize DataverseClient

TBD

Create new Entity

It is possible to create a new Entity using the DataverseClient. This requires a full EntityMetadata definition according to Dataverse standards. You can make this yourself and follow the MetadataDumper protocol, or use the provided define_entity function.

The define_label function makes it simple to generate Label metadata with correct LocalizedLabels in its payload.

In the example below, the optional return_representation argument has been set to True to receive the full Entity metadata definition as created by Dataverse as part of the server response. The response can be parsed by EntityMetadata classmethod to get a full fledged object for editing.

from dataverse_api.metadata.attributes import StringAttributeMetadata
from dataverse_api.metadata.entity import EntityMetadata, define_entity
from dataverse_api.utils.labels import define_label

new_entity = define_entity(
    schema_name="new_name",
    attributes=[StringAttributeMetadata(
        schema_name="new_primary_col",
        is_primary_name = True,
        description=define_label("Primary column for Entity."),
        display_name=define_label("Autonumber Column"),
        auto_number_format="{SEQNUM:6}-#-{RANDSTRING:3}")],
    description=define_label("Entity Created by Client"),
    display_name=define_label("Programmatically Created Table")
)

resp = client.create_entity(new_entity, return_representation=True)
entity_meta = EntityMetadata.model_validate_dataverse(resp.json())

Update existing Entity

You can update an existing Entity definition easily by retrieving the Entity metadata definition, and reupload an adjusted version.

Below is a simple example. Note that this method also supports return_representation in the same manner as the DataverseClient.create_entity() method, if you want to return the edited Entity metadata as persisted in Dataverse.

metadata = client.get_entity_definition("new_name")
metadata.display_name.localized_labels[0].label = "Overridden Display Name"

client.update_entity(metadata)

DataverseEntity

Initialize interface with Entity

To initializes an interface with a specific Dataverse Entity, use the DataverseClient.entity() method. It returns a DataverseEntity object that allows interaction with this specific entity.

entity = client.entity(logical_name="foo")

As of now, only LogicalName is supported for instantiating a new DataverseEntity object.

Read

TBD

Create

TBD

Upsert

TBD

Delete

TBD

Add and remove Attributes

TBD

Add and remove Alternate Keys

TBD

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dataverse_api-1.0.1.tar.gz (24.6 kB view hashes)

Uploaded Source

Built Distribution

dataverse_api-1.0.1-py3-none-any.whl (28.6 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page