{"id":41623778,"url":"https://github.com/climateimpactlab/impactlab_api_mockup_2","last_synced_at":"2026-01-24T14:03:44.452Z","repository":{"id":70039915,"uuid":"84376037","full_name":"ClimateImpactLab/impactlab_api_mockup_2","owner":"ClimateImpactLab","description":null,"archived":false,"fork":false,"pushed_at":"2017-03-09T01:15:09.000Z","size":26,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-09-10T03:51:39.462Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClimateImpactLab.png","metadata":{"files":{"readme":"README.ipynb","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2017-03-08T23:24:15.000Z","updated_at":"2017-03-09T00:38:57.000Z","dependencies_parsed_at":"2023-03-02T06:30:32.492Z","dependency_job_id":null,"html_url":"https://github.com/ClimateImpactLab/impactlab_api_mockup_2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ClimateImpactLab/impactlab_api_mockup_2","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClimateImpactLab%2Fimpactlab_api_mockup_2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClimateImpactLab%2Fimpactlab_api_mockup_2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClimateImpactLab%2Fimpactlab_api_mockup_2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClimateImpactLab%2Fimpactlab_api_mockup_2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClimateImpactLab","download_url":"https://codeload.github.com/ClimateImpactLab/impactlab_api_mockup_2/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClimateImpactLab%2Fimpactlab_api_mockup_2/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28729411,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-24T10:24:43.181Z","status":"ssl_error","status_checked_at":"2026-01-24T10:24:36.112Z","response_time":89,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-24T14:02:30.476Z","updated_at":"2026-01-24T14:03:44.434Z","avatar_url":"https://github.com/ClimateImpactLab.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 1,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"from __future__ import absolute_import\\n\",\n    \"from impactlab import impactlab\\n\",\n    \"from impactlab.mockfs import DataAPI, Variable, SuperIndex\\n\",\n    \"\\n\",\n    \"import pandas as pd\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 2,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# initialize the mockup of a DataFS api with variable support\\n\",\n    \"api = DataAPI()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Specifying a simple pipeline job\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"The goal is to have the ability to write atomic pipeline components and then map them across our data sets.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"#### Example: multiply `popop` by `tas`\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 3,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"def compute_mortality(popop, tas):\\n\",\n    \"    '''\\n\",\n    \"    Demonstrates a simple atomic computation\\n\",\n    \"    '''\\n\",\n    \"\\n\",\n    \"    return popop.value * tas.value\\n\",\n    \"\\n\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This can be parameterized using the `impactlab.uses` functions and run using `impactlab.updates`:\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 4,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"@impactlab.uses(popop=api.get_variable('/GCP/socioeconomics/popop'), tas=api.get_variable('/GCP/climate/tas'))\\n\",\n    \"@impactlab.iters()\\n\",\n    \"@impactlab.updates(api.get_variable('/GCP/impacts/mortality'))\\n\",\n    \"def mortality(popop, tas):\\n\",\n    \"    '''\\n\",\n    \"    Demonstrates a simple computation job\\n\",\n    \"\\n\",\n    \"    The `impactlab.uses` decorator accepts keyword arguments of the form \\n\",\n    \"    {name: obj}, where name is the name of argument to pass and obj is a mockfs\\n\",\n    \"    Variable object.\\n\",\n    \"\\n\",\n    \"    The `impactlab.iters` decorator drives a for-loop over all combinations of\\n\",\n    \"    indices for the given variables.\\n\",\n    \"\\n\",\n    \"    The value returned by the decorated function is used to update the value of\\n\",\n    \"    the variable specified by `impactlab.updates` for the given indices.\\n\",\n    \"    '''\\n\",\n    \"\\n\",\n    \"    return compute_mortality(popop, tas)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"To see this in action, simply call `mortality`:\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 5,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"\u003cArchive /GCP/impacts/mortality/rcp26/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp45/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp60/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp26/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp45/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp60/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp26/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp45/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp60/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp26/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp45/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp60/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp26/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp45/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp60/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"mortality()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"To run a subset of the jobs, slice the variables in the `@impactlab.uses` calls:\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 6,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"@impactlab.uses(popop=api.get_variable('/GCP/socioeconomics/popop'))\\n\",\n    \"@impactlab.uses(tas=api.get_variable('/GCP/climate/tas')[{'rcp': 'rcp85'}])\\n\",\n    \"@impactlab.iters()\\n\",\n    \"@impactlab.updates(api.get_variable('/GCP/impacts/mortality'))\\n\",\n    \"def mortality_rcp85(popop, tas):\\n\",\n    \"    '''\\n\",\n    \"    `impactlab_uses` may be supplied as many times as desired (but must be above\\n\",\n    \"    impactlab.updates or other functional decorators).\\n\",\n    \"    \\n\",\n    \"    Slicing variables is done with a dictionary specifying the index to be sliced\\n\",\n    \"    '''\\n\",\n    \"\\n\",\n    \"    return compute_mortality(popop, tas)\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Note that this function only iterates over `rcp85`:\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 7,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp1.nc\u003e bumped 0.0.2 --\u003e 0.0.3\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp2.nc\u003e bumped 0.0.2 --\u003e 0.0.3\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp3.nc\u003e bumped 0.0.2 --\u003e 0.0.3\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp4.nc\u003e bumped 0.0.2 --\u003e 0.0.3\\n\",\n      \"\u003cArchive /GCP/impacts/mortality/rcp85/ssp5.nc\u003e bumped 0.0.2 --\u003e 0.0.3\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"mortality_rcp85()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"## Running a complex ETL Job\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"Let's say you want to perform a job that loads one class of variables into memory, then iterates over another set while keeping the first set alive.\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"This can be done using a two-stage job using the `iters` decorator:\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 8,\n   \"metadata\": {\n    \"collapsed\": true\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"@impactlab.uses(tas=api.get_variable('/GCP/climate/tas'))\\n\",\n    \"@impactlab.iters()\\n\",\n    \"def tas2_ir(tas):\\n\",\n    \"    '''\\n\",\n    \"    Demonstrates a two-stage ETL process\\n\",\n    \"    '''\\n\",\n    \"\\n\",\n    \"    with tas.open('r') as f:\\n\",\n    \"        tas_data = pd.read_csv(f)\\n\",\n    \"\\n\",\n    \"    @impactlab.uses(tas=tas)\\n\",\n    \"    @impactlab.uses(popop=api.get_variable('/GCP/socioeconomics/popop'))\\n\",\n    \"    @impactlab.iters()\\n\",\n    \"    @impactlab.updates(api.get_variable('/GCP/climate/tas2_ir'))\\n\",\n    \"    def inner(popop, tas):\\n\",\n    \"        '''\\n\",\n    \"        The inner loop's uses() decorator is given tas as an argument. The\\n\",\n    \"        `iters` decorator sees that tas is an archive rather than a variable\\n\",\n    \"        and simply passes the value through rather than attempting to loop over\\n\",\n    \"        it.\\n\",\n    \"        '''\\n\",\n    \"\\n\",\n    \"        with popop.open('r') as f:\\n\",\n    \"            popop_data = pd.read_csv(f)\\n\",\n    \"\\n\",\n    \"        return (tas_data**2) * popop_data\\n\",\n    \"\\n\",\n    \"    inner()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"When this is run, note how the climate data is only loaded once per outer loop:\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": 9,\n   \"metadata\": {\n    \"collapsed\": false\n   },\n   \"outputs\": [\n    {\n     \"name\": \"stdout\",\n     \"output_type\": \"stream\",\n     \"text\": [\n      \"loading \u003cArchive /GCP/climate/tas/rcp26.nc\u003e\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp1.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp26/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp2.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp26/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp3.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp26/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp4.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp26/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp5.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp26/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/climate/tas/rcp45.nc\u003e\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp1.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp45/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp2.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp45/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp3.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp45/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp4.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp45/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp5.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp45/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/climate/tas/rcp60.nc\u003e\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp1.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp60/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp2.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp60/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp3.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp60/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp4.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp60/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp5.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp60/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/climate/tas/rcp85.nc\u003e\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp1.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp85/ssp1.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp2.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp85/ssp2.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp3.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp85/ssp3.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp4.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp85/ssp4.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\",\n      \"loading \u003cArchive /GCP/socioeconomics/popop/ssp5.nc\u003e\\n\",\n      \"\u003cArchive /GCP/climate/tas2_ir/rcp85/ssp5.nc\u003e bumped 0.0.1 --\u003e 0.0.2\\n\"\n     ]\n    }\n   ],\n   \"source\": [\n    \"tas2_ir()\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"metadata\": {},\n   \"source\": [\n    \"nifty!\"\n   ]\n  }\n ],\n \"metadata\": {\n  \"anaconda-cloud\": {},\n  \"kernelspec\": {\n   \"display_name\": \"Python [conda env:datafs]\",\n   \"language\": \"python\",\n   \"name\": \"conda-env-datafs-py\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 2\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython2\",\n   \"version\": \"2.7.12\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 1\n}\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclimateimpactlab%2Fimpactlab_api_mockup_2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclimateimpactlab%2Fimpactlab_api_mockup_2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclimateimpactlab%2Fimpactlab_api_mockup_2/lists"}