ultibi


Nameultibi JSON
Version 0.6.0 PyPI version JSON
download
home_pageNone
SummaryFlexible DataFrame Operations via UI
upload_time2023-12-24 12:58:17
maintainerNone
docs_urlNone
authorNone
requires_python>=3.7
licenseNone
keywords dataframe visualization pivot table pivottable aggregation calculation chart data dataviz pivot-table frtb risk
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            <br>

<p align="center">
    <a href="https://ultimabi.uk/" target="_blank">
    <img width="900" src="https://ultima-bi.s3.eu-west-2.amazonaws.com/imgs/logo.png" alt="Ultima Logo">
    </a>
</p>
<br>

<h3 align="center">the ultimate data analytics tool <br> for no code visualisation and collaborative exploration.</h3>

<h3 align="center">Present easier. &nbsp; Dig deeper. &nbsp; Review together. &nbsp;</h3>

# The Ultimate BI tool
With `Ultibi` you can turn your `DataFrame` into a pivot table with a UI and share it across organisation. You can also define measures applicable to your `DataFrame`.  This means your colleagues/consumers don't have to write any code to analyse the data.

<br>

<p align="center">
    <a href="https://frtb.demo.ultimabi.uk/" target="_blank">
    <img width="900" src="https://ultima-bi.s3.eu-west-2.amazonaws.com/imgs/UltimaScreenshotExplained.jpg" alt="Ultima Logo">
    </a>
</p>

<br>

Ultibi leverages on the giants: [Actix](https://github.com/actix/actix-web), [Polars](https://github.com/pola-rs/polars) and Rust which make this possible. We use TypeScript for the frontend.

# Examples

Our [userguide](https://ultimabi.uk/ultibi-frtb-book/)

## Python
`pip install ultibi`

### Quickstart
```python
import ultibi as ul
import polars as pl
import os
os.environ["RUST_LOG"] = "info" # enable logs
os.environ["ADDRESS"] = "0.0.0.0:8000" # host on this address

# Read Data
# for more details: https://pola-rs.github.io/polars/py-polars/html/reference/api/polars.read_csv.html
df = pl.read_csv("titanic.csv")

# Convert it into an Ultibi DataSet
ds = ul.DataSet.from_frame(df)

# By default (might change in the future)
# Fields are Utf8 (non numerics) and integers
# Measures are numeric columns.
ds.ui() 
```

Then navigate to `http://localhost:8000` or checkout `http://localhost:8000/swagger-ui` for the OpenAPI documentation.

### More flexible - custom measures
```python
import ultibi as ul
import polars as pl
import os
os.environ["RUST_LOG"] = "info" # enable logs
os.environ["ADDRESS"] = "0.0.0.0:8000" # host on this address

# Read Data
# for more details: https://pola-rs.github.io/polars/py-polars/html/reference/api/polars.read_csv.html
df = pl.read_csv("titanic.csv")

# Let's add some Custom/Bespoke Calculations to our UI

# Standard Calculator
def survival_mean_age(kwargs: dict[str, str]) -> pl.Expr:
    """Mean Age of Survivals
    pl.col("survived") is 0 or 1
    pl.col("age") * pl.col("survived") - age of survived person, otherwise 0
    pl.col("survived").sum() - number of survived
    """
    return pl.col("age") * pl.col("survived") / pl.col("survived").sum()

# Also a Standard Calculator
def example_dep_calc(kwargs: dict[str, str]) -> pl.Expr:
    return pl.col("SurvivalMeanAge_sum") + pl.col("SouthamptonFareDivAge_sum")

# When we need more involved calculations we go for a Custom Calculator
def custom_calculator(
            srs: list[pl.Series], kwargs: dict[str, str]
        ) -> pl.Series:
        """
        Southampton Fare/Age*multiplier
        """
        df = pl.DataFrame({"age": srs[0], 
                           "fare": srs[1], 
                           "e": srs[2]}) 
        # Add Indicator Column for Southampton
        df = df.with_columns(pl.when(pl.col("e")=="S").then(1).otherwise(0).alias("S")) 
        multiplier = float(kwargs.get("multiplier", 1))
        res = df["S"] * df["fare"] / df["age"] * multiplier
        return res

# inputs for the custom_calculator srs param
inputs = ["age", "fare", "embarked"]
# We return Floats
res_type = pl.Float64
# We return a Series, not a scalar (which otherwise would be auto exploded)
returns_scalar = False

measures = [
            ul.BaseMeasure(
                "SouthamptonFareDivAge",
                ul.CustomCalculator(
                    custom_calculator, res_type, inputs, returns_scalar
                ),
                # (Optional) - we are only interested in Southampton, so
                # unless other measures requested we might as well filter for Southampton only
                # However, if if multiple measures requested, their precompute_filters will be joined as OR.
                [[ul.EqFilter("embarked", "S")]],
                # PARAMS tab of the UI
                calc_params=[ul.CalcParam("mltplr", "1", "float")]
            ),
            ul.BaseMeasure(
                "SurvivalMeanAge",
                ul.StandardCalculator(survival_mean_age),
                aggregation_restriction="sum",
            ),
            ul.DependantMeasure(
                "A_Dependant_Measure",
                ul.StandardCalculator(example_dep_calc),
                [("SurvivalMeanAge", "sum"), ("SouthamptonFareDivAge", "sum")],
            ),
        ]

# Convert it into an Ultibi DataSet
ds = ul.DataSet.from_frame(df, bespoke_measures=measures)

# By default (might change in the future)
# Fields are Utf8 (non numerics) and integers
# Measures are numeric columns.
ds.ui() 
```

You can also wite Rust native Custom calculators measure which wouldn't be bounded by GIL! Checkout the [userguide](https://ultimabi.uk/ultibi-frtb-book/).

### DataSources - In and OutOf memory
We provide aim to support different sources of the data. 
```python
scan = pl.read_csv("../frtb_engine/data/frtb/Delta.csv", 
                           dtypes={"SensitivitySpot": pl.Float64})
dsource = ul.DataSource.inmemory(scan)
ds = ul.DataSet.from_source(dsource)
ds.prepare() # .prepare() is only relevant to FRTB dataset currently
ds.ui()
```
If you don't want to/can't hold all your data in the process memory, you can sacrifise performance for memory with Scan/DataBase
```python
import polars as pl
import ultibi as ul
# Note that the LazyFrame query must start with scan_
# and must've NOT been collected
scan = pl.scan_csv("../frtb_engine/data/frtb/Delta.csv", 
                    dtypes={"SensitivitySpot": pl.Float64})
dsource = ul.DataSource.scan(scan)
ds = ul.DataSet.from_source(dsource)
ds.ui()
```

Note: Naturally the later two options will be slower, because prior to computing your measures we will need to read the relevant bits of the data into the process memory. 

### FRTB SA
[FRTB SA](https://en.wikipedia.org/wiki/Fundamental_Review_of_the_Trading_Book) is a great usecase for `ultibi`. FRTB SA is a set of standardised, computationally intensive rules established by the regulator. High business impact of these rules manifests in need for **analysis** and **visibility** thoroughout an organisation. Note: Ultima is not a certified aggregator. Always benchmark the results against your own interpretation of the rules.
See python frtb [userguide](https://ultimabi.uk/ultibi-frtb-book/).

### Polars Compatibility 
| Ultibi      | Polars |
| ----------- | ----------- |
| 0.5      | 18.7       |
| 0.6   | 19.18        |

### License 
Licensor:             Ultibi Ltd.
Licensed Work:        Ultima
                      The Licensed Work is (c) 2023 Ultibi Ltd.

`ultibi` python library is made available for the purpose of demonstrating the possibilities offered by the Software so users can evaluate the possibilities and potential of the Software. You can choose one of the following:

1) [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.html) 

2) Proprietary License. Allows you to use the software in whichever way you want. These `licenses` are extremely affordable, and you can check out the options by reaching out to us directly, via `anatoly at ultimabi dot uk`, or by visiting `ultimabi dot uk`

### No Liability
As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.

### Contributions
All code in this Repository is a property of the Licensor. If you make a contribution via PR or any other way, you give the Licensor a right to use your code in whatever way they deem necessary, including copying or refactoring it to a private repository, provided that a copy of your work will remain available under the current conditions.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "ultibi",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.7",
    "maintainer_email": null,
    "keywords": "dataframe,visualization,pivot,table,pivottable,aggregation,calculation,chart,data,dataviz,pivot-table,frtb,risk",
    "author": null,
    "author_email": "Anatoly Bugakov <anatoly@ultimabi.uk>",
    "download_url": "https://files.pythonhosted.org/packages/97/7a/e05671bc661039ed81a8b2c618fdab28aeeefc6537d17f656b74bbcea911/ultibi-0.6.0.tar.gz",
    "platform": null,
    "description": "<br>\n\n<p align=\"center\">\n    <a href=\"https://ultimabi.uk/\" target=\"_blank\">\n    <img width=\"900\" src=\"https://ultima-bi.s3.eu-west-2.amazonaws.com/imgs/logo.png\" alt=\"Ultima Logo\">\n    </a>\n</p>\n<br>\n\n<h3 align=\"center\">the ultimate data analytics tool <br> for no code visualisation and collaborative exploration.</h3>\n\n<h3 align=\"center\">Present easier. &nbsp; Dig deeper. &nbsp; Review together. &nbsp;</h3>\n\n# The Ultimate BI tool\nWith `Ultibi` you can turn your `DataFrame` into a pivot table with a UI and share it across organisation. You can also define measures applicable to your `DataFrame`.  This means your colleagues/consumers don't have to write any code to analyse the data.\n\n<br>\n\n<p align=\"center\">\n    <a href=\"https://frtb.demo.ultimabi.uk/\" target=\"_blank\">\n    <img width=\"900\" src=\"https://ultima-bi.s3.eu-west-2.amazonaws.com/imgs/UltimaScreenshotExplained.jpg\" alt=\"Ultima Logo\">\n    </a>\n</p>\n\n<br>\n\nUltibi leverages on the giants: [Actix](https://github.com/actix/actix-web), [Polars](https://github.com/pola-rs/polars) and Rust which make this possible. We use TypeScript for the frontend.\n\n# Examples\n\nOur [userguide](https://ultimabi.uk/ultibi-frtb-book/)\n\n## Python\n`pip install ultibi`\n\n### Quickstart\n```python\nimport ultibi as ul\nimport polars as pl\nimport os\nos.environ[\"RUST_LOG\"] = \"info\" # enable logs\nos.environ[\"ADDRESS\"] = \"0.0.0.0:8000\" # host on this address\n\n# Read Data\n# for more details: https://pola-rs.github.io/polars/py-polars/html/reference/api/polars.read_csv.html\ndf = pl.read_csv(\"titanic.csv\")\n\n# Convert it into an Ultibi DataSet\nds = ul.DataSet.from_frame(df)\n\n# By default (might change in the future)\n# Fields are Utf8 (non numerics) and integers\n# Measures are numeric columns.\nds.ui() \n```\n\nThen navigate to `http://localhost:8000` or checkout `http://localhost:8000/swagger-ui` for the OpenAPI documentation.\n\n### More flexible - custom measures\n```python\nimport ultibi as ul\nimport polars as pl\nimport os\nos.environ[\"RUST_LOG\"] = \"info\" # enable logs\nos.environ[\"ADDRESS\"] = \"0.0.0.0:8000\" # host on this address\n\n# Read Data\n# for more details: https://pola-rs.github.io/polars/py-polars/html/reference/api/polars.read_csv.html\ndf = pl.read_csv(\"titanic.csv\")\n\n# Let's add some Custom/Bespoke Calculations to our UI\n\n# Standard Calculator\ndef survival_mean_age(kwargs: dict[str, str]) -> pl.Expr:\n    \"\"\"Mean Age of Survivals\n    pl.col(\"survived\") is 0 or 1\n    pl.col(\"age\") * pl.col(\"survived\") - age of survived person, otherwise 0\n    pl.col(\"survived\").sum() - number of survived\n    \"\"\"\n    return pl.col(\"age\") * pl.col(\"survived\") / pl.col(\"survived\").sum()\n\n# Also a Standard Calculator\ndef example_dep_calc(kwargs: dict[str, str]) -> pl.Expr:\n    return pl.col(\"SurvivalMeanAge_sum\") + pl.col(\"SouthamptonFareDivAge_sum\")\n\n# When we need more involved calculations we go for a Custom Calculator\ndef custom_calculator(\n            srs: list[pl.Series], kwargs: dict[str, str]\n        ) -> pl.Series:\n        \"\"\"\n        Southampton Fare/Age*multiplier\n        \"\"\"\n        df = pl.DataFrame({\"age\": srs[0], \n                           \"fare\": srs[1], \n                           \"e\": srs[2]}) \n        # Add Indicator Column for Southampton\n        df = df.with_columns(pl.when(pl.col(\"e\")==\"S\").then(1).otherwise(0).alias(\"S\")) \n        multiplier = float(kwargs.get(\"multiplier\", 1))\n        res = df[\"S\"] * df[\"fare\"] / df[\"age\"] * multiplier\n        return res\n\n# inputs for the custom_calculator srs param\ninputs = [\"age\", \"fare\", \"embarked\"]\n# We return Floats\nres_type = pl.Float64\n# We return a Series, not a scalar (which otherwise would be auto exploded)\nreturns_scalar = False\n\nmeasures = [\n            ul.BaseMeasure(\n                \"SouthamptonFareDivAge\",\n                ul.CustomCalculator(\n                    custom_calculator, res_type, inputs, returns_scalar\n                ),\n                # (Optional) - we are only interested in Southampton, so\n                # unless other measures requested we might as well filter for Southampton only\n                # However, if if multiple measures requested, their precompute_filters will be joined as OR.\n                [[ul.EqFilter(\"embarked\", \"S\")]],\n                # PARAMS tab of the UI\n                calc_params=[ul.CalcParam(\"mltplr\", \"1\", \"float\")]\n            ),\n            ul.BaseMeasure(\n                \"SurvivalMeanAge\",\n                ul.StandardCalculator(survival_mean_age),\n                aggregation_restriction=\"sum\",\n            ),\n            ul.DependantMeasure(\n                \"A_Dependant_Measure\",\n                ul.StandardCalculator(example_dep_calc),\n                [(\"SurvivalMeanAge\", \"sum\"), (\"SouthamptonFareDivAge\", \"sum\")],\n            ),\n        ]\n\n# Convert it into an Ultibi DataSet\nds = ul.DataSet.from_frame(df, bespoke_measures=measures)\n\n# By default (might change in the future)\n# Fields are Utf8 (non numerics) and integers\n# Measures are numeric columns.\nds.ui() \n```\n\nYou can also wite Rust native Custom calculators measure which wouldn't be bounded by GIL! Checkout the [userguide](https://ultimabi.uk/ultibi-frtb-book/).\n\n### DataSources - In and OutOf memory\nWe provide aim to support different sources of the data. \n```python\nscan = pl.read_csv(\"../frtb_engine/data/frtb/Delta.csv\", \n                           dtypes={\"SensitivitySpot\": pl.Float64})\ndsource = ul.DataSource.inmemory(scan)\nds = ul.DataSet.from_source(dsource)\nds.prepare() # .prepare() is only relevant to FRTB dataset currently\nds.ui()\n```\nIf you don't want to/can't hold all your data in the process memory, you can sacrifise performance for memory with Scan/DataBase\n```python\nimport polars as pl\nimport ultibi as ul\n# Note that the LazyFrame query must start with scan_\n# and must've NOT been collected\nscan = pl.scan_csv(\"../frtb_engine/data/frtb/Delta.csv\", \n                    dtypes={\"SensitivitySpot\": pl.Float64})\ndsource = ul.DataSource.scan(scan)\nds = ul.DataSet.from_source(dsource)\nds.ui()\n```\n\nNote: Naturally the later two options will be slower, because prior to computing your measures we will need to read the relevant bits of the data into the process memory. \n\n### FRTB SA\n[FRTB SA](https://en.wikipedia.org/wiki/Fundamental_Review_of_the_Trading_Book) is a great usecase for `ultibi`. FRTB SA is a set of standardised, computationally intensive rules established by the regulator. High business impact of these rules manifests in need for **analysis** and **visibility** thoroughout an organisation. Note: Ultima is not a certified aggregator. Always benchmark the results against your own interpretation of the rules.\nSee python frtb [userguide](https://ultimabi.uk/ultibi-frtb-book/).\n\n### Polars Compatibility \n| Ultibi      | Polars |\n| ----------- | ----------- |\n| 0.5      | 18.7       |\n| 0.6   | 19.18        |\n\n### License \nLicensor:             Ultibi Ltd.\nLicensed Work:        Ultima\n                      The Licensed Work is (c) 2023 Ultibi Ltd.\n\n`ultibi` python library is made available for the purpose of demonstrating the possibilities offered by the Software so users can evaluate the possibilities and potential of the Software. You can choose one of the following:\n\n1) [GNU GPL v3](https://www.gnu.org/licenses/gpl-3.0.html) \n\n2) Proprietary License. Allows you to use the software in whichever way you want. These `licenses` are extremely affordable, and you can check out the options by reaching out to us directly, via `anatoly at ultimabi dot uk`, or by visiting `ultimabi dot uk`\n\n### No Liability\nAs far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.\n\n### Contributions\nAll code in this Repository is a property of the Licensor. If you make a contribution via PR or any other way, you give the Licensor a right to use your code in whatever way they deem necessary, including copying or refactoring it to a private repository, provided that a copy of your work will remain available under the current conditions.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Flexible DataFrame Operations via UI",
    "version": "0.6.0",
    "project_urls": {
        "Documentation": "https://ultimabi.uk/ultibi-frtb-book/",
        "Homepage": "https://ultimabi.uk/",
        "Repository": "https://github.com/ultima-ib/ultibi-frtb-book"
    },
    "split_keywords": [
        "dataframe",
        "visualization",
        "pivot",
        "table",
        "pivottable",
        "aggregation",
        "calculation",
        "chart",
        "data",
        "dataviz",
        "pivot-table",
        "frtb",
        "risk"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3fccc5bd3b7df15022f9d9e743cbbbcfb000a93b56db72d3079c4b406045f86f",
                "md5": "e284fec477b351512e6a99e9015fcf23",
                "sha256": "6b47dfa20e47c61c732ad0ff38102a6db2cebf335bffec1f587f5f943e8cb787"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-macosx_10_12_x86_64.whl",
            "has_sig": false,
            "md5_digest": "e284fec477b351512e6a99e9015fcf23",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 23316731,
            "upload_time": "2023-12-24T12:57:40",
            "upload_time_iso_8601": "2023-12-24T12:57:40.943973Z",
            "url": "https://files.pythonhosted.org/packages/3f/cc/c5bd3b7df15022f9d9e743cbbbcfb000a93b56db72d3079c4b406045f86f/ultibi-0.6.0-cp37-abi3-macosx_10_12_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "58a364004769c81b9f26f2dd4772290f7b5c4af8b532a38e4d7fc642bd4215a2",
                "md5": "6f71070f011b0478398c78230071be3e",
                "sha256": "544227aabbcf89c7017579e0220a1c0c86f69d649ca64870efafe97c00455340"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-macosx_11_0_arm64.whl",
            "has_sig": false,
            "md5_digest": "6f71070f011b0478398c78230071be3e",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 21898018,
            "upload_time": "2023-12-24T12:57:46",
            "upload_time_iso_8601": "2023-12-24T12:57:46.318382Z",
            "url": "https://files.pythonhosted.org/packages/58/a3/64004769c81b9f26f2dd4772290f7b5c4af8b532a38e4d7fc642bd4215a2/ultibi-0.6.0-cp37-abi3-macosx_11_0_arm64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "57845c9fce2775e1ec21b86984cb1775fe520a2ecb72c96fdac0175d462171c2",
                "md5": "ef222fc611f7051ae8424da6267fab28",
                "sha256": "c031f4cae3357f2e460a11f53e1515cdfb2975c3eba0712f9695a1550dc3fc6b"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
            "has_sig": false,
            "md5_digest": "ef222fc611f7051ae8424da6267fab28",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 28952675,
            "upload_time": "2023-12-24T12:57:50",
            "upload_time_iso_8601": "2023-12-24T12:57:50.381858Z",
            "url": "https://files.pythonhosted.org/packages/57/84/5c9fce2775e1ec21b86984cb1775fe520a2ecb72c96fdac0175d462171c2/ultibi-0.6.0-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "6b94012dbdf42b1b719f8147b182cf2d6825e3776becb1e81afd672e5042eca4",
                "md5": "9f4efd41e863664c5fe38b06a387ce4b",
                "sha256": "e8d45104252b9d4fde3f388e7159e88a70cd490f04de96d5ce4a376354b80940"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl",
            "has_sig": false,
            "md5_digest": "9f4efd41e863664c5fe38b06a387ce4b",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 31928177,
            "upload_time": "2023-12-24T12:57:53",
            "upload_time_iso_8601": "2023-12-24T12:57:53.768077Z",
            "url": "https://files.pythonhosted.org/packages/6b/94/012dbdf42b1b719f8147b182cf2d6825e3776becb1e81afd672e5042eca4/ultibi-0.6.0-cp37-abi3-manylinux_2_17_i686.manylinux2014_i686.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "7d63a7eeb5e3ae2c806936736f31fe958310a8bb18c6a10236b2a3f1eb1a1ed3",
                "md5": "24ce2549c020d58b1a7221077c44a183",
                "sha256": "8ac240ef518215d1840b8c31e2a2acf2da8565b3bc0213b315681d6ca94b8919"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
            "has_sig": false,
            "md5_digest": "24ce2549c020d58b1a7221077c44a183",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 36905136,
            "upload_time": "2023-12-24T12:57:57",
            "upload_time_iso_8601": "2023-12-24T12:57:57.677266Z",
            "url": "https://files.pythonhosted.org/packages/7d/63/a7eeb5e3ae2c806936736f31fe958310a8bb18c6a10236b2a3f1eb1a1ed3/ultibi-0.6.0-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "8395c5dd7478aa3f84b7ccccc2df2117c939bc0d8100afda7e73c1f1c3b9a79a",
                "md5": "2500a61d6fa7a4ac78e3c9781cb2d23b",
                "sha256": "e4bc7ee3297bf684869e6fbbe0e198e79de26905d9b0e93fb2a9a4c4e786f4b0"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "has_sig": false,
            "md5_digest": "2500a61d6fa7a4ac78e3c9781cb2d23b",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 30765620,
            "upload_time": "2023-12-24T12:58:01",
            "upload_time_iso_8601": "2023-12-24T12:58:01.380160Z",
            "url": "https://files.pythonhosted.org/packages/83/95/c5dd7478aa3f84b7ccccc2df2117c939bc0d8100afda7e73c1f1c3b9a79a/ultibi-0.6.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0bc3736b74931ea47cef5b16552f99f10eace82b14796a6ea80cb58c163d2f95",
                "md5": "4e5585a3d8b89b9a851accd6e7d7e1b2",
                "sha256": "3e4b4e299c57b06ea7b81f50a587d5abb5622bef507f8c5bb3d57c9b7291ff8a"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-manylinux_2_28_aarch64.whl",
            "has_sig": false,
            "md5_digest": "4e5585a3d8b89b9a851accd6e7d7e1b2",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 29958338,
            "upload_time": "2023-12-24T12:58:04",
            "upload_time_iso_8601": "2023-12-24T12:58:04.990103Z",
            "url": "https://files.pythonhosted.org/packages/0b/c3/736b74931ea47cef5b16552f99f10eace82b14796a6ea80cb58c163d2f95/ultibi-0.6.0-cp37-abi3-manylinux_2_28_aarch64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "59cc95dc371da929e5a82ab07ef60665b18ecfb026d49030e7287d9387f3a348",
                "md5": "270ce6f2b2fd550745d3a08a2f2ed44c",
                "sha256": "c1c33df8d0f4a1ae05c7ffa55db3f9882ac8174598af173ede12bc26802a30b7"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-win32.whl",
            "has_sig": false,
            "md5_digest": "270ce6f2b2fd550745d3a08a2f2ed44c",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 19016066,
            "upload_time": "2023-12-24T12:58:10",
            "upload_time_iso_8601": "2023-12-24T12:58:10.621684Z",
            "url": "https://files.pythonhosted.org/packages/59/cc/95dc371da929e5a82ab07ef60665b18ecfb026d49030e7287d9387f3a348/ultibi-0.6.0-cp37-abi3-win32.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "0b979c8a50d0aed712ae4e988bcf7ccd5044f3ff56a07b238b92b23cc0f2c070",
                "md5": "adc5b59a476429c9cb2faa26f3d46f35",
                "sha256": "8669adadba4f22b080feba82198acd339095f88325535cf7d72d271ecc6672f0"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0-cp37-abi3-win_amd64.whl",
            "has_sig": false,
            "md5_digest": "adc5b59a476429c9cb2faa26f3d46f35",
            "packagetype": "bdist_wheel",
            "python_version": "cp37",
            "requires_python": ">=3.7",
            "size": 21270890,
            "upload_time": "2023-12-24T12:58:14",
            "upload_time_iso_8601": "2023-12-24T12:58:14.120777Z",
            "url": "https://files.pythonhosted.org/packages/0b/97/9c8a50d0aed712ae4e988bcf7ccd5044f3ff56a07b238b92b23cc0f2c070/ultibi-0.6.0-cp37-abi3-win_amd64.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "977ae05671bc661039ed81a8b2c618fdab28aeeefc6537d17f656b74bbcea911",
                "md5": "e6cc51c99aa250f229753a8e63448bd7",
                "sha256": "3c408c74bbbc22133e2eb0d9c54bda54e61132e0857a8c377e6839c78ec079f5"
            },
            "downloads": -1,
            "filename": "ultibi-0.6.0.tar.gz",
            "has_sig": false,
            "md5_digest": "e6cc51c99aa250f229753a8e63448bd7",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.7",
            "size": 181425,
            "upload_time": "2023-12-24T12:58:17",
            "upload_time_iso_8601": "2023-12-24T12:58:17.565638Z",
            "url": "https://files.pythonhosted.org/packages/97/7a/e05671bc661039ed81a8b2c618fdab28aeeefc6537d17f656b74bbcea911/ultibi-0.6.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-12-24 12:58:17",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ultima-ib",
    "github_project": "ultibi-frtb-book",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [],
    "lcname": "ultibi"
}
        
Elapsed time: 0.15418s