def get_codes( cls, display_query: Optional[str] = None, sample_size: Optional[int] = None, exclude_meta_tag=True, **kwargs, ): """Find all codes See possible argments for `phc.easy.query.Query.get_codes` Examples -------- >>> import phc.easy as phc >>> phc.Auth.set({'account': '<your-account-name>'}) >>> phc.Project.set_current('My Project Name') >>> >>> phc.Observation.get_codes(patient_id="<id>", max_pages=3) """ code_fields = [*cls.code_fields(), *kwargs.get("code_fields", [])] # Meta tag can significantly clutter things up since it's often a date # value instead of a real code if exclude_meta_tag: code_fields = [ field for field in code_fields if field != "meta.tag" ] return Query.get_codes( display_query=display_query, sample_size=sample_size, table_name=cls.table_name(), code_fields=code_fields, **without_keys(kwargs, ["code_fields"]), )
def flatten_nested_dicts(codeable_dict): NESTED_TYPES = [ ("valueCodeableConcept", get_value_codeable_concept_items), ("extension", lambda x: x), ] base_dict = without_keys(codeable_dict, [key for key, _ in NESTED_TYPES]) def reduce_nested(acc, nested_type): key, func = nested_type if key in codeable_dict: return [ *acc, *[{ **base_dict, **(merge_codeable_and_prefix(*flatten_and_find_prefix( result, key))), } for result in func(codeable_dict[key])], ] return acc flattened = reduce(reduce_nested, NESTED_TYPES, []) if len(flattened) == 0: # At least include the top-level dictionary attributes return [base_dict] return flattened
def test_without_keys(): assert without_keys({ "a": "z", "b": "y", "c": "x" }, ["b", "c"]) == { "a": "z" }
def get_value_codeable_concept_items(concept): "Extracts dictionaries in a valueCodeableConcept" base_concept = without_keys(concept, ["coding"]) if "coding" not in concept: return [base_concept] return [{ **base_concept, **(merge_codeable_and_prefix(*flatten_and_find_prefix( coding_value, "coding"))), } for coding_value in concept["coding"]]
def flatten_and_find_prefix(codeable_dict, prefix): """ Convert a codeable_dict type to a flattened dictionary or list of dictionaries for simple prefixing """ if "tag" in codeable_dict: return ( [without_keys(codeable_dict, ["tag"]), *codeable_dict["tag"]], join_underscore([prefix, "tag"]), ) if "url" in codeable_dict: return ( flatten_nested_dicts(without_keys(codeable_dict, ["url"])), join_underscore( [prefix, "url_", system_to_column(codeable_dict["url"]) + "_"]), ) if "system" in codeable_dict: return ( without_keys(codeable_dict, ["system"]), join_underscore([ prefix, "system_", system_to_column(codeable_dict["system"]) + "_", ]), ) if "type" in codeable_dict and "value" in codeable_dict: types = codeable_dict["type"]["coding"] return ( [{ **t, **without_keys(codeable_dict, ["type"]) } for t in types], join_underscore(["type", "coding", prefix]), ) return (codeable_dict, prefix)
def get_data_frame( cls, name: Optional[str] = None, auth_args: Auth = Auth.shared(), max_pages: Optional[int] = None, page_size: Optional[int] = None, log: bool = False, show_progress: bool = False, ): """Execute a request for projects ## Parameters Query: `phc.easy.projects.ProjectListOptions` Execution: `phc.easy.query.Query.execute_paging_api` """ if page_size is None: # Projects do not have much data so use a higher page size page_size = 100 get_data_frame = super().get_data_frame auth = Auth(auth_args) get_data_frame_args = without_keys( cls._get_current_args(inspect.currentframe(), locals()), ["auth_args", "account", "show_progress"], ) def get_projects_for_account(account: dict): df = get_data_frame( ignore_cache=True, all_results=max_pages is None, auth_args=auth.customized({"account": account["id"]}), show_progress=show_progress, **get_data_frame_args, ) df["account"] = account["id"] return df frame = pd.concat(list(pmap(get_projects_for_account, auth.accounts()))) return frame.reset_index(drop=True)