Skip to content

Commit

Permalink
0.5.3 pythonnet upgrade (#97)
Browse files Browse the repository at this point in the history
* update pythonnet and clr-loader

* drop python version 3.7 support

* added python version 3.11 and 3.12 support

* update pbix testing file
  • Loading branch information
Curts0 authored Sep 16, 2024
1 parent 3b72d93 commit eac4a07
Show file tree
Hide file tree
Showing 33 changed files with 70 additions and 19 deletions.
14 changes: 9 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,28 @@ build-backend = "setuptools.build_meta"

[project]
name = "python_tabular"
version = "0.5.2"
version = "0.5.3"
authors = [
{ name="Curtis Stallings", email="curtisrstallings@gmail.com" },
]
dependencies = [
"pythonnet==3.0.0a2",
"clr-loader==0.1.7",
"pythonnet==3.0.3",
"clr-loader==0.2.6",
"xmltodict==0.13.0",
"pandas>=1.4.3",
"requests>=2.28.1",
"rich>=12.5.1"
]
description = "Connect to your tabular model and perform operations programmatically"
readme = "README.md"
requires-python = ">=3.7"
requires-python = ">=3.8"
classifiers = [
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Development Status :: 3 - Alpha",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Development Status :: 5 - Production/Stable",
"Operating System :: Microsoft",
"License :: OSI Approved :: MIT License"
]
Expand Down
1 change: 1 addition & 0 deletions pytabular/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
It will setup logging and make sure Pythonnet is good to go.
Then it will begin to import specifics of the module.
"""

# flake8: noqa
import logging
import os
Expand Down
15 changes: 11 additions & 4 deletions pytabular/best_practice_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
It is used with tabular_editor.py to run BPA.
I did not want to re-invent the wheel, so just letting TE2 work it's magic.
"""

import logging
import requests as r
import atexit
Expand All @@ -20,7 +21,8 @@ def download_bpa_file(
"https://raw.githubusercontent.com/microsoft/Analysis-Services/master/BestPracticeRules/BPARules.json" # noqa: E501
),
folder: str = "Best_Practice_Analyzer",
auto_remove=True,
auto_remove: bool = True,
verify: bool = False,
) -> str:
"""Download a BPA file from local or web.
Expand All @@ -34,6 +36,7 @@ def download_bpa_file(
folder (str, optional): New folder string.
Defaults to 'Best_Practice_Analyzer'.
auto_remove (bool, optional): Auto Remove when script exits. Defaults to True.
verify (bool, optional): Passthrough argument for `r.get`. Need to update later.
Returns:
str: File path for the newly downloaded BPA.
Expand All @@ -42,7 +45,7 @@ def download_bpa_file(
folder_location = os.path.join(os.getcwd(), folder)
if os.path.exists(folder_location) is False:
os.makedirs(folder_location)
response = r.get(download_location)
response = r.get(download_location, verify=verify)
file_location = os.path.join(folder_location, download_location.split("/")[-1])
with open(file_location, "w", encoding="utf-8") as bpa:
json.dump(response.json(), bpa, ensure_ascii=False, indent=4)
Expand All @@ -55,7 +58,9 @@ def download_bpa_file(
class BPA:
"""Setting BPA Class for future work..."""

def __init__(self, file_path: str = "Default") -> None:
def __init__(
self, file_path: str = "Default", verify_download: bool = True
) -> None:
"""BPA class to be used with the TE2 class.
You can create the BPA class without any arguments.
Expand All @@ -64,10 +69,12 @@ def __init__(self, file_path: str = "Default") -> None:
Args:
file_path (str, optional): See `Download_BPA_File()`. Defaults to "Default".
verify_download (bool, optional): Passthrough argument for `r.get`.
Need to update later.
"""
logger.debug(f"Initializing BPA Class:: {file_path}")
if file_path == "Default":
self.location: str = download_bpa_file()
self.location: str = download_bpa_file(verify=verify_download)
else:
self.location: str = file_path
pass
1 change: 1 addition & 0 deletions pytabular/column.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Once connected to your model, interacting with column(s) will be done through these classes.
"""

import logging
import pandas as pd
from pytabular.object import PyObject, PyObjects
Expand Down
7 changes: 4 additions & 3 deletions pytabular/culture.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""`culture.py` is used to house the `PyCulture`, and `PyCultures` classes."""

import logging
from pytabular.object import PyObject, PyObjects
from typing import List
Expand Down Expand Up @@ -29,9 +30,9 @@ def set_translation(self) -> List[dict]:
{
"object_translation": translation.Value,
"object_name": translation.Object.Name,
"object_parent_name": translation.Object.Parent.Name
if translation.Object.Parent
else "",
"object_parent_name": (
translation.Object.Parent.Name if translation.Object.Parent else ""
),
"object_type": str(translation.Property),
}
for translation in self._object.ObjectTranslations
Expand Down
1 change: 1 addition & 0 deletions pytabular/document.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This module can generate pages in markdown for use in Docusaurus.
"""

import logging

from pathlib import Path
Expand Down
1 change: 1 addition & 0 deletions pytabular/logic_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""`logic_utils` used to store multiple functions that are used in many different files."""

import logging
import datetime
import os
Expand Down
1 change: 1 addition & 0 deletions pytabular/measure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Once connected to your model, interacting with measure(s)
will be done through these classes.
"""

import logging
import pandas as pd
from pytabular.object import PyObject, PyObjects
Expand Down
1 change: 1 addition & 0 deletions pytabular/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
These classes are used with the others (Tables, Columns, Measures, Partitions, etc.).
"""

from __future__ import annotations
from abc import ABC
from rich.console import Console
Expand Down
1 change: 1 addition & 0 deletions pytabular/partition.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Once connected to your model, interacting with partition(s) will be done through these classes.
"""

import logging

from pytabular.object import PyObject, PyObjects
Expand Down
1 change: 1 addition & 0 deletions pytabular/pbi_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
The main function is `find_local_pbi_instances()`.
It will find any open PBIX files on your computer and spit out a connection string for you.
"""

import pytabular as p
import subprocess

Expand Down
3 changes: 2 additions & 1 deletion pytabular/pytabular.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Main class is `Tabular()`. Use that for connecting with your models.
"""

import logging

from Microsoft.AnalysisServices.Tabular import (
Expand Down Expand Up @@ -491,7 +492,7 @@ def analyze_bpa(
logger.debug("Beginning request to talk with TE2 & Find BPA...")
bim_file_location = f"{os.getcwd()}\\Model.bim"
atexit.register(remove_file, bim_file_location)
cmd = f'{tabular_editor_exe} "Provider=MSOLAP;\
cmd = f'"{tabular_editor_exe}" "Provider=MSOLAP;\
{self.Adomd.ConnectionString}" {self.Database.Name} -B "{bim_file_location}" \
-A {best_practice_analyzer} -V/?'
logger.debug("Command Generated")
Expand Down
1 change: 1 addition & 0 deletions pytabular/query.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
)
```
"""

import logging
import os
from typing import Union
Expand Down
1 change: 1 addition & 0 deletions pytabular/refresh.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
model.Tables['Sales'].Partitions['Last Fiscal Year'].refresh()
```
"""

from tabular_tracing import RefreshTrace, BaseTrace
import logging
from Microsoft.AnalysisServices.Tabular import (
Expand Down
1 change: 1 addition & 0 deletions pytabular/relationship.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Once connected to your model, interacting with relationship(s)
will be done through these classes.
"""

import logging
from pytabular.object import PyObject, PyObjects
from pytabular.table import PyTable, PyTables
Expand Down
1 change: 1 addition & 0 deletions pytabular/table.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Once connected to your model, interacting with table(s) will be done through these classes.
"""

import logging
import pandas as pd
from pytabular.partition import PyPartition, PyPartitions
Expand Down
13 changes: 10 additions & 3 deletions pytabular/tabular_editor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
Or you can input your own location.
"""

import logging
import os
import requests as r
Expand All @@ -18,6 +19,7 @@ def download_tabular_editor(
),
folder: str = "Tabular_Editor_2",
auto_remove=True,
verify=False,
) -> str:
"""Runs a request.get() to retrieve the zip file from web.
Expand All @@ -31,14 +33,15 @@ def download_tabular_editor(
folder (str, optional): New Folder Location. Defaults to "Tabular_Editor_2".
auto_remove (bool, optional): Boolean to determine auto
removal of files once script exits. Defaults to True.
verify (bool, optional): Passthrough argument for `r.get`. Need to update later.
Returns:
str: File path of TabularEditor.exe
"""
logger.info("Downloading Tabular Editor 2...")
logger.info(f"From... {download_location}")
folder_location = os.path.join(os.getcwd(), folder)
response = r.get(download_location)
response = r.get(download_location, verify=verify)
file_location = f"{os.getcwd()}\\{download_location.split('/')[-1]}"
with open(file_location, "wb") as te2_zip:
te2_zip.write(response.content)
Expand All @@ -59,7 +62,9 @@ class TabularEditor:
Mainly runs `download_tabular_editor()`
"""

def __init__(self, exe_file_path: str = "Default") -> None:
def __init__(
self, exe_file_path: str = "Default", verify_download: bool = True
) -> None:
"""Init for `TabularEditor()` class.
This is mostly a placeholder right now.
Expand All @@ -69,10 +74,12 @@ def __init__(self, exe_file_path: str = "Default") -> None:
exe_file_path (str, optional): File path where TE2 lives. Defaults to "Default".
If "Default", it will run `download_tabular_editor()`
and download from github.
verify_download (bool, optional): Passthrough argument for `r.get`.
Need to update later.
"""
logger.debug(f"Initializing Tabular Editor Class:: {exe_file_path}")
if exe_file_path == "Default":
self.exe: str = download_tabular_editor()
self.exe: str = download_tabular_editor(verify=verify_download)
else:
self.exe: str = exe_file_path
pass
1 change: 1 addition & 0 deletions pytabular/tabular_tracing.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
2. If you want to see the FULL query then set logging to DEBUG.
3. You can drop on your own, or will get dropped on script exit.
"""

import logging
import random
import xmltodict
Expand Down
Binary file modified test/adventureworks/AdventureWorks Sales.pbix
Binary file not shown.
1 change: 1 addition & 0 deletions test/config.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Custom configurations for pytest."""

import pytabular as p
import os
import pandas as pd
Expand Down
1 change: 1 addition & 0 deletions test/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
This file also has functions that give instructions on start and finish of pytest.
See `config.py` for more testing configurations.
"""

from test.config import (
local_pbix,
testingtablename,
Expand Down
7 changes: 6 additions & 1 deletion test/run_versions.bat
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
@echo on
pyenv shell 3.7.9 & python3 -m pytest & pyenv shell 3.8.9 & python3 -m pytest & pyenv shell 3.9.13 & python3 -m pytest & pyenv shell 3.10.6 & python3 -m pytest & pause & pause
pyenv shell 3.8.9 & python3 -m pytest &
pyenv shell 3.9.13 & python3 -m pytest &
pyenv shell 3.10.6 & python3 -m pytest &
pyenv shell 3.11.9 & python3 -m pytest &
pyenv shell 3.12.6 & python3 -m pytest &
pause & pause
1 change: 1 addition & 0 deletions test/test_10logic_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""pytest for the table.py file. Covers the PyTable and PyTables classes."""

from test.config import testing_parameters
import pytest
from pytabular import logic_utils
Expand Down
1 change: 1 addition & 0 deletions test/test_11document.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Tests to cover the document.py file."""

from test.config import testing_parameters
import pytest
import pytabular as p
Expand Down
1 change: 1 addition & 0 deletions test/test_1sanity.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Does 1 actually equal 1?
Or am I crazy person about to descend into madness.
"""

import pytest
from Microsoft.AnalysisServices.Tabular import Database
from test.config import testing_parameters
Expand Down
1 change: 1 addition & 0 deletions test/test_2object.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""pytest for the table.py file. Covers the PyTable and PyTables classes."""

from test.config import testing_parameters
import pytest
from pytabular import Tabular
Expand Down
1 change: 1 addition & 0 deletions test/test_3tabular.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Bulk of pytests for `Tabular()` class."""

import pytest
import pandas as pd
import pytabular as p
Expand Down
1 change: 1 addition & 0 deletions test/test_4measure.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Bulk of pytests for `PyMeasure()` class."""

import pytest
from test.config import testing_parameters

Expand Down
1 change: 1 addition & 0 deletions test/test_5column.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""pytest for the column.py file. Covers the PyColumn and PyColumns classes."""

from test.config import testing_parameters, testingtablename
import pytest
import pandas as pd
Expand Down
1 change: 1 addition & 0 deletions test/test_6table.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""pytest for the table.py file. Covers the PyTable and PyTables classes."""

from test.config import testing_parameters, testingtablename
import pytest
import pandas as pd
Expand Down
1 change: 1 addition & 0 deletions test/test_7tabular_tracing.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""pytest for the table.py file. Covers the PyTable and PyTables classes."""

from test.config import testing_parameters, testingtablename
import pytest
import pytabular as p
Expand Down
5 changes: 3 additions & 2 deletions test/test_8bpa.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""pytest for bpa."""

import pytest
import pytabular as p
from test.config import testing_parameters
Expand All @@ -8,8 +9,8 @@
@pytest.mark.parametrize("model", testing_parameters)
def test_bpa(model):
"""Testing execution of `model.analyze_bpa()`."""
te2 = p.TabularEditor().exe
bpa = p.BPA().location
te2 = p.TabularEditor(verify_download=False).exe
bpa = p.BPA(verify_download=False).location
assert isinstance(model.analyze_bpa(te2, bpa), list)


Expand Down
1 change: 1 addition & 0 deletions test/test_9custom.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
These were designed selfishly for my own uses.
So seperating out... To one day sunset and remove.
"""

from test.config import testing_parameters, testingtablename
import pytest

Expand Down

0 comments on commit eac4a07

Please sign in to comment.