Documentation Index
Fetch the complete documentation index at: https://docs.activeviam.com/llms.txt
Use this file to discover all available pages before exploring further.
property Cube.restrictions : MutableMapping[str, MembershipCondition[LevelIdentifier, ‘IN’, bool | int | float | date | datetime | time | str] | RelationalCondition[LevelIdentifier, ‘EQ’, bool | int | float | date | datetime | time | str] | LogicalCondition[MembershipCondition[LevelIdentifier, ‘IN’, bool | int | float | date | datetime | time | str] | RelationalCondition[LevelIdentifier, ‘EQ’, bool | int | float | date | datetime | time | str], ‘AND’]]
Mapping from role to the corresponding restriction.
Restrictions limit the data accessible to users based on their roles.
- Restrictions on different hierarchies are intersected.
- Restrictions on the same hierarchy are unioned.
Example
>>> session_config = tt.SessionConfig(security=tt.SecurityConfig())
>>> session = tt.Session.start(session_config)
>>> df = pd.DataFrame(
... [
... ("Asia", "Korea", "KRW"),
... ("Asia", "Japan", "JPY"),
... ("Europe", "France", "EUR"),
... ("Europe", "Germany", "EUR"),
... ("Europe", "Norway", "NOK"),
... ("Europe", "Sweden", "SEK"),
... ],
... columns=["Continent", "Country", "Currency"],
... )
>>> table = session.read_pandas(
... df,
... keys={"Continent", "Country", "Currency"},
... table_name="Restrictions example",
... )
>>> cube = session.create_cube(table)
>>> h, l, m = cube.hierarchies, cube.levels, cube.measures
>>> cube.hierarchies["Geography"] = [
... table["Continent"],
... table["Country"],
... ]
>>> for level_name in cube.hierarchies["Geography"]:
... del cube.hierarchies[level_name]
Adding a user to the session:
>>> session.security.individual_roles["Rose"] = {"ROLE_USER"}
>>> password = "abcdef123456"
>>> session.security.basic_authentication.credentials["Rose"] = password
>>> rose_session = tt.Session.connect(
... session.url,
... authentication=tt.BasicAuthentication("Rose", password),
... )
>>> rose_cube = rose_session.cubes[cube.name]
ROLE_USER has no restrictions so all the countries and currencies are accessible from the cube:
>>> rose_cube.query(
... m["contributors.COUNT"], levels=[l["Country"], l["Currency"]]
... )
contributors.COUNT
Continent Country Currency
Asia Japan JPY 1
Korea KRW 1
Europe France EUR 1
Germany EUR 1
Norway NOK 1
Sweden SEK 1
Assigning a role to Rose to limit her access to France only:
>>> cube.restrictions["ROLE_FRANCE"] = l["Country"] == "France"
>>> cube.restrictions["ROLE_FRANCE"]
l['Restrictions example', 'Geography', 'Country'] == 'France'
>>> session.security.individual_roles["Rose"] |= {"ROLE_FRANCE"}
>>> rose_cube.query(
... m["contributors.COUNT"], include_totals=True, levels=[l["Country"]]
... )
contributors.COUNT
Continent Country
Total 1
Europe 1
France 1
Unlike atoti.tables.Tables.restrictions, cube restrictions have no impact on tables:
>>> rose_table = rose_session.tables[table.name]
>>> rose_table.query().set_index(["Continent", "Country"]).sort_index()
Currency
Continent Country
Asia Japan JPY
Korea KRW
Europe France EUR
Germany EUR
Norway NOK
Sweden SEK
Adding Lena with ROLE_GERMANY limiting her access to Germany only:
>>> cube.restrictions["ROLE_GERMANY"] = l["Country"] == "Germany"
>>> session.security.basic_authentication.credentials["Lena"] = password
>>> session.security.individual_roles["Lena"] = {
... "ROLE_GERMANY",
... "ROLE_USER",
... }
>>> lena_session = tt.Session.connect(
... session.url,
... authentication=tt.BasicAuthentication("Lena", password),
... )
>>> lena_cube = lena_session.cubes[cube.name]
>>> lena_cube.query(m["contributors.COUNT"], levels=[l["Country"]])
contributors.COUNT
Continent Country
Europe Germany 1
Assigning ROLE_GERMANY to Rose lets her access the union of the restricted countries:
>>> session.security.individual_roles["Rose"] |= {"ROLE_GERMANY"}
>>> cube.restrictions
{'ROLE_FRANCE': l['Restrictions example', 'Geography', 'Country'] == 'France', 'ROLE_GERMANY': l['Restrictions example', 'Geography', 'Country'] == 'Germany'}
>>> rose_cube.query(m["contributors.COUNT"], levels=[l["Country"]])
contributors.COUNT
Continent Country
Europe France 1
Germany 1
Restrictions can include multiple elements:
>>> cube.restrictions["ROLE_NORDIC"] = l["Country"].isin("Norway", "Sweden")
>>> session.security.individual_roles["Rose"] |= {"ROLE_NORDIC"}
>>> rose_cube.query(m["contributors.COUNT"], levels=[l["Country"]])
contributors.COUNT
Continent Country
Europe France 1
Germany 1
Norway 1
Sweden 1
Since Country and Continent are part of the same Geography hierarchy, restrictions on these two levels are unioned:
>>> cube.restrictions["ROLE_ASIA"] = l["Continent"] == "Asia"
>>> session.security.individual_roles["Rose"] |= {"ROLE_ASIA"}
>>> rose_cube.query(m["contributors.COUNT"], levels=[l["Country"]])
contributors.COUNT
Continent Country
Asia Japan 1
Korea 1
Europe France 1
Germany 1
Norway 1
Sweden 1
Currency is part of a different hierarchy so restrictions on it are intersected with the ones from Geography:
>>> cube.restrictions["ROLE_EUR"] = l["Currency"] == "EUR"
>>> session.security.individual_roles["Rose"] |= {"ROLE_EUR"}
>>> rose_cube.query(
... m["contributors.COUNT"], levels=[l["Country"], l["Currency"]]
... )
contributors.COUNT
Continent Country Currency
Europe France EUR 1
Germany EUR 1
Removing the ROLE_FRANCE and ROLE_GERMANY roles leaves no remaining accessible countries:
>>> session.security.individual_roles["Rose"] -= {
... "ROLE_FRANCE",
... "ROLE_GERMANY",
... }
>>> rose_cube.query(m["contributors.COUNT"], levels=[l["Country"]])
Empty DataFrame
Columns: [contributors.COUNT]
Index: []
A QuerySession has cubes but no tables so there is nothing to merge cube restrictions with.
However, data cubes have their restrictions merged with the ones from the session’s tables:
>>> session.tables.restrictions.update(
... {
... "ROLE_SEK": table["Currency"] == "SEK",
... "ROLE_JPY": table["Currency"] == "JPY",
... }
... )
>>> session.security.individual_roles["Rose"] = {
... "ROLE_ASIA", # Cube restriction
... "ROLE_NORDIC", # Cube restriction
... "ROLE_SEK", # Tables restriction
... "ROLE_JPY", # Tables restriction
... "ROLE_USER",
... }
>>> rose_table.query().set_index(["Continent", "Country"]).sort_index()
Currency
Continent Country
Asia Japan JPY
Europe Sweden SEK
>>> rose_cube.query(
... m["contributors.COUNT"], levels=[l["Country"], l["Currency"]]
... )
contributors.COUNT
Continent Country Currency
Asia Japan JPY 1
Europe Sweden SEK 1
>>> cube.restrictions.clear()
>>> cube.restrictions
{}