def test_evaluate_chaining_volatile(self): import importlib from liquer import evaluate import liquer.ext.basic from liquer.commands import reset_command_registry reset_command_registry() # prevent double-registration # Hack to enforce registering of the commands importlib.reload(liquer.ext.basic) @first_command(volatile=True) def test_volatile(): return 123 @first_command def test_nonvolatile(): return 234 @command def test_callable2(x): # has state as a first argument return x * 10 state1 = evaluate("test_volatile/test_callable2") assert state1.get() == 1230 assert state1.is_volatile() state2 = evaluate("test_nonvolatile/test_callable2") assert state2.get() == 2340 assert not state2.is_volatile()
def test_evaluate_chaining_exceptions(self): import importlib from liquer import evaluate import liquer.ext.basic from liquer.commands import reset_command_registry reset_command_registry() # prevent double-registration # Hack to enforce registering of the commands importlib.reload(liquer.ext.basic) @command(ABC="def", ns="testns", context_menu="menu") def test_callable1(state, a: int, b=123): # has state as a first argument return a + b @command def test_callable2(state): # has state as a first argument return state state1 = evaluate("ns-testns/test_callable1-1") assert state1.get() == 124 assert state1.metadata["attributes"]["ABC"] == "def" assert state1.metadata["attributes"]["ns"] == "testns" assert state1.metadata["attributes"]["context_menu"] == "menu" state2 = evaluate("ns-testns/test_callable1-1/test_callable2") assert state2.get() == 124 assert state2.metadata["attributes"]["ABC"] == "def" assert state2.metadata["attributes"].get("ns") != "testns" assert "context_menu" not in state2.metadata["attributes"]
def test_registration_namespace(self): import importlib from liquer import evaluate import liquer.ext.basic from liquer.commands import reset_command_registry reset_command_registry() # prevent double-registration # Hack to enforce registering of the commands importlib.reload(liquer.ext.basic) assert "flag" in command_registry().as_dict()["root"] try: @command(ns="new") def flag(state, name): return f"New definition of flag called with {name}" redefined = True except: redefined = False assert redefined # assert evaluate("/flag-test-f/flag-test/state_variable-test").get() == True # assert evaluate("/flag-test-f/ns-root/flag-test/state_variable-test").get() == True assert evaluate( "/flag-test-f/ns-new/flag-test/state_variable-test").get() == False # Cleanup reset_command_registry() # prevent double-registration # Hack to enforce registering of the commands importlib.reload(liquer.ext.basic)
def test_clean_recipes(self): import importlib from liquer import evaluate import liquer.ext.basic import liquer.ext.meta import liquer.store as st from liquer.commands import reset_command_registry reset_command_registry() # prevent double-registration # Hack to enforce registering of the commands importlib.reload(liquer.ext.basic) importlib.reload(liquer.ext.meta) @first_command def hello(x): return f"Hello, {x}" substore = st.MemoryStore() substore.store( "recipes.yaml", """ RECIPES: - hello-RECIPES/hello1.txt subdir: - hello-subdir/hello2.txt """, {}, ) store = RecipeSpecStore(substore) store_backup = st.get_store() st.set_store(store) try: assert store.get_metadata("hello1.txt")["status"] == Status.RECIPE.value assert store.get_metadata("subdir/hello2.txt")["status"] == Status.RECIPE.value assert store.get_bytes("hello1.txt") == b"Hello, RECIPES" assert store.get_bytes("subdir/hello2.txt") == b"Hello, subdir" assert store.get_metadata("hello1.txt")["status"] == Status.READY.value assert store.get_metadata("subdir/hello2.txt")["status"] == Status.READY.value assert evaluate("-R-meta/subdir/-/ns-meta/clean_recipes").get()["removed"] == ["subdir/hello2.txt"] assert store.get_metadata("hello1.txt")["status"] == Status.READY.value assert store.get_metadata("subdir/hello2.txt")["status"] == Status.RECIPE.value finally: st.set_store(store_backup)
def filter_country(df, countryiso, country_of="originating"): """Keep only rows for one country - originating or residing. A column "Country" with column names of the variable country (residing or originating) is created. """ countries_table = evaluate( "countries" ).get() # evaluate rather than call, so that the cache is used country_map = dict(zip(countries_table.iso3, countries_table.country)) coo, coa = country_columns(df) is_originating = country_of.lower().startswith("o") fixed_country_column = coo if is_originating else coa variable_country_column = coa if is_originating else coo df = df.loc[df[fixed_country_column] == countryiso, :] df["Country"] = [country_map.get(c, "") for c in df[variable_country_column]] return df
def test_serialized_registration(self): from liquer import evaluate reset_command_registry() def f(x: int): return x * 102 metadata = command_metadata_from_callable(f, has_state_argument=False, attributes={}) b = command_registry().encode_registration(f, metadata) enable_remote_registration() command_registry().register_remote_serialized(b) assert evaluate("f-3").get() == 306 reset_command_registry() disable_remote_registration()
def report_solutions(countryiso): "Create a report as html for solutions for a specific country" countries_table = evaluate( "countries" ).get() # evaluate rather than call, so that the cache is used country_map = dict(zip(countries_table.iso3, countries_table.country)) country_name = country_map.get(countryiso) return evaluate_template( f""" <html> <head> <title>Solutions - {country_name}</title> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"> </head> <body> <h1>Solutions - {country_name}</h1> <div class="container"> <div class="row"> <div class="col-sm"> <h4>Last year solutions by country for refugees originating from {country_name}</h4> $solutions/convert-f/filter_country-{countryiso}-originating/last_year/totals_per-Country/solutions_bar-Country$ </div> <div class="col-sm"> <h4>Last year solutions by country for refugees residing in {country_name}</h4> $solutions/convert-f/filter_country-{countryiso}-residing/last_year/totals_per-Country/solutions_bar-Country$ </div> </div> <div class="row"> <div class="col-sm"> <h4>Solutions by year for refugees originating from {country_name}</h4> $solutions/convert-f/filter_country-{countryiso}-originating/totals_per-Year/solutions_bar-Year$ </div> <div class="col-sm"> <h4>Solutions by year for refugees residing in {country_name}</h4> $solutions/convert-f/filter_country-{countryiso}-residing/totals_per-Year/solutions_bar-Year$ </div> </div> </div> </body> </html> """ )
def countries(): "Table of countries (iso3 and country name) used in the data" countries = set() for data in [ "asylum_applications", "asylum_decisions", "demographics", "population_totals", "solutions", ]: df = evaluate(data).get() countries.update(df.ISO3CoO) countries.update(df.ISO3CoA) countries = sorted(countries) countrynames = [ # Country.get_country_name_from_iso3(countryiso) for countryiso in countries Get_Country_Name_From_ISO3_Extended(countryiso) for countryiso in countries ] return pd.DataFrame(dict(iso3=countries, country=countrynames))
def reports(): "Table of all reports for all countries" countries_table = evaluate( "countries" ).get() # evaluate rather than call, so that the cache is used dict(zip(countries_table.iso3, countries_table.country)) rows = "".join( f""" <tr> <th>{row.country}</th> <td>{row.iso3}</td> <td> <a href="/liquer/q/report_applications-{row.iso3}/applications_{row.iso3}.html">applications</a>, <a href="/liquer/q/report_decisions-{row.iso3}/decisions_{row.iso3}.html">decisions</a>, <a href="/liquer/q/report_demographics-{row.iso3}/demographics_{row.iso3}.html">demographics</a>, <a href="/liquer/q/report_population_totals-{row.iso3}/population_totals_{row.iso3}.html">population totals</a>, <a href="/liquer/q/report_solutions-{row.iso3}/solutions_{row.iso3}.html">solutions</a> </td> </tr>""" for index, row in countries_table.iterrows() ) return f"""
def test_cache_attribute_equality_rules(self): from liquer import evaluate, first_command cache1 = MemoryCache() cache2 = MemoryCache() cache3 = MemoryCache() set_cache( cache1.if_attribute_equal("abc", 123) + cache2.if_attribute_not_equal("xyz", 456) + cache3 ) @first_command(abc=123) def command1a(): return "C1" @first_command(xyz=456) def command2a(): return "C2" @first_command def command3a(): return "C3" evaluate("command1a") evaluate("command2a") evaluate("command3a") assert "command1a" in cache1.storage assert "command1a" not in cache2.storage assert "command1a" not in cache3.storage assert cache1.storage["command1a"].get() == "C1" assert "command2a" not in cache1.storage assert "command2a" not in cache2.storage assert "command2a" in cache3.storage assert cache3.storage["command2a"].get() == "C2" assert "command3a" not in cache1.storage assert "command3a" in cache2.storage assert "command3a" not in cache3.storage assert cache2.storage["command3a"].get() == "C3" set_cache(None)
def test_cache_rules(self): from liquer import evaluate, first_command cache1 = MemoryCache() cache2 = MemoryCache() cache3 = MemoryCache() set_cache(cache1.if_contains("abc") + cache2.if_not_contains("xyz") + cache3) @first_command(abc=True) def command1(): return "C1" @first_command(xyz=True) def command2(): return "C2" @first_command def command3(): return "C3" evaluate("command1") evaluate("command2") evaluate("command3") assert "command1" in cache1.storage assert "command1" not in cache2.storage assert "command1" not in cache3.storage assert cache1.storage["command1"].get() == "C1" assert "command2" not in cache1.storage assert "command2" not in cache2.storage assert "command2" in cache3.storage assert cache3.storage["command2"].get() == "C2" assert "command3" not in cache1.storage assert "command3" in cache2.storage assert "command3" not in cache3.storage assert cache2.storage["command3"].get() == "C3" set_cache(None)