-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* boilerplate cli * wrap sources cli * Feature/required args (#10) * create api decorator to check valid args * format files * add args validation for releases * add api arg validator for categories * update required args for categories namespace * add required args to tags namespace * add validate args to sources apis * add arg validation to series namespace * add required args for series apis * finish base implementation of all APIs, closes issue #4 * bump fred-py-api to 0.0.5 and update readme to point to wiki * Create dependabot.yml * Delete dependabot.yml * Feature/test suite (#11) * basic tests for categories namespace * add basic tests for tags api * add basic tests for sources api namespace * create basic tests for releases api namespace * add basic tests for series api namespace * create test for decorators * use src for tests * first full test-suite of basic API functionality, closes issue #8 * new CI for lint and test package * upgrade black in CI, use fred api key from GH secrets * reformat files * update CI only test for 3.9 & 3.10 * only run CI with python 3.10.x * run ci using coverage * add coverage upload * add new job skeleton to CI * upload to PyPI when publishing new release/prerelease * Feature/test suite (#14) * basic tests for categories namespace * add basic tests for tags api * add basic tests for sources api namespace * create basic tests for releases api namespace * add basic tests for series api namespace * create test for decorators * use src for tests * first full test-suite of basic API functionality, closes issue #8 * new CI for lint and test package * upgrade black in CI, use fred api key from GH secrets * reformat files * update CI only test for 3.9 & 3.10 * only run CI with python 3.10.x * run ci using coverage * add coverage upload * add new job skeleton to CI * upload to PyPI when publishing new release/prerelease * update readme * 0.0.7-Alpha (#16) * add FRED urls to python docstrings * update readme * bump lib * fix issue #15 by enforcing API length * check alnum * update tests * reformat file * rename top level packagename to fred * bump lib (#17) * Add support for XML `file_type` (#18) * add XML support, and associated test * bump lib version to v0.1.1 * move cli library * cli WIP * general idea of FRED cli, WIP * variadic api arguments and kwargs generator, import cleanups * re-organize internal util module * full CLI project skeleton with some working examples * json dump string in sources CLI * restructure tests module * adding dummy test case for codecov * adding dummy test case for codecov * reformat file * update ci to run coverage with src * add test for generate_api_kwargs cli utility * Added JSON CLI commands for each command * update tests module to use installed fred library * update local requirements * update cli code slightly * update pyproject.toml to include new deps and script entrypoints * update README to include CLI * update github ci workflow to include editable install * Fixed many issues in code review, still need 4 utility functions, few changes needed * update a few args, docstrings, and file format * Adding basic testing structure for sources cli * wip series test cases * refactor fred cli entry point * refactor common test case logic * refactor and fix existing api tests * fix api key mock for cli tests * update ci workflow * slight refactor to base fred client test setup * allow for more testing constraints in base framework * wip series cli tests * omit test * add all basic tests for releases namespace * add missing test to releases namespace * finish up all basic tests for series cli * add support for XML output in CLI * Added CLI test cases for sources, tags, categories * reformat files * fix up some broken tests * add new test for CLI entry point * optimize imports * update codecoverage omit files, and CI * fix CI * ignore unnecessary files in codecov * update pyproject.toml description Co-authored-by: Zachary Spar <zachspar@gmail.com> Co-authored-by: Zachary Spar <41600414+zachspar@users.noreply.github.com>
- Loading branch information
1 parent
c15b84d
commit 3513e02
Showing
32 changed files
with
1,624 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/usr/bin/env python3 | ||
from .cli import * | ||
from .decorators import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
FRED CLI Utilities. | ||
""" | ||
from json import dumps | ||
from typing import Union | ||
from xml.etree import ElementTree as ET | ||
|
||
|
||
__all__ = [ | ||
"generate_api_kwargs", | ||
"serialize", | ||
] | ||
|
||
|
||
def generate_api_kwargs(arguments: tuple) -> dict: | ||
"""Generate API keyword arguments from CLI variadic arguments.""" | ||
api_kwargs = {} | ||
for arg in arguments: | ||
try: | ||
api_kwargs[arg.split("=")[0]] = arg.split("=")[1] | ||
except IndexError: | ||
pass | ||
return api_kwargs | ||
|
||
|
||
def serialize(response_obj: Union[dict, ET.Element]) -> str: | ||
"""Serialize a FRED response object to a string.""" | ||
if isinstance(response_obj, dict): | ||
return dumps(response_obj, indent=4) | ||
elif isinstance(response_obj, ET.Element): | ||
return ET.tostring(response_obj, encoding="unicode", method="xml") | ||
else: | ||
raise TypeError("response_obj must be a dict or xml.etree.ElementTree.Element") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#!/usr/bin/env python3 | ||
"""CLI Core.""" | ||
import click | ||
from click import group | ||
|
||
from fred import FredAPI | ||
from .categories import categories | ||
from .releases import releases | ||
from .series import series | ||
from .sources import sources | ||
from .tags import tags | ||
|
||
__all__ = [ | ||
"fred_cli", | ||
] | ||
|
||
|
||
@group() | ||
@click.option("--api-key", type=click.STRING, required=False, help="FRED API key.") | ||
@click.pass_context | ||
def fred_cli(ctx, api_key: str): | ||
"""CLI for the Federal Reserve Economic Data (FRED).""" | ||
ctx.ensure_object(dict) | ||
ctx.obj["api_key"] = api_key | ||
ctx.obj["client"] = FredAPI(api_key=api_key) | ||
|
||
|
||
# add each FRED command group | ||
fred_cli.add_command(categories) | ||
fred_cli.add_command(releases) | ||
fred_cli.add_command(series) | ||
fred_cli.add_command(sources) | ||
fred_cli.add_command(tags) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#!/usr/bin/env python3 | ||
import click | ||
|
||
from . import fred_cli | ||
|
||
|
||
def run_cli(): | ||
"""Run the FRED CLI.""" | ||
try: | ||
fred_cli(auto_envvar_prefix="FRED") | ||
except AssertionError: | ||
click.echo(click.style("Error: FRED_API_KEY is not set!", fg="red")) | ||
|
||
|
||
if __name__ == "__main__": | ||
run_cli() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
#!/usr/bin/env python3 | ||
""" | ||
FRED CLI - Categories Namespace. | ||
""" | ||
import click | ||
|
||
from .. import BaseFredAPIError | ||
from .._util import generate_api_kwargs, serialize | ||
|
||
__all__ = [ | ||
"categories", | ||
] | ||
|
||
|
||
@click.group() | ||
@click.pass_context | ||
def categories(ctx): | ||
""" | ||
Categories CLI Namespace. | ||
""" | ||
pass | ||
|
||
|
||
@categories.command() | ||
@click.option("--category-id", "-i", required=True, type=click.STRING, help="Category ID.") | ||
@click.argument("args", nargs=-1) | ||
@click.pass_context | ||
def get_category(ctx, category_id: int, args: tuple): | ||
"""Get a category.""" | ||
try: | ||
click.echo(serialize(ctx.obj["client"].get_category(category_id, **generate_api_kwargs(args)))) | ||
except (ValueError, BaseFredAPIError) as e: | ||
raise click.UsageError(click.style(e, fg="red"), ctx) | ||
|
||
|
||
@categories.command() | ||
@click.option("--category-id", "-i", required=True, type=click.STRING, help="Category ID.") | ||
@click.argument("args", nargs=-1) | ||
@click.pass_context | ||
def get_category_children(ctx, category_id: int, args: tuple): | ||
"""Get the child categories.""" | ||
try: | ||
click.echo(serialize(ctx.obj["client"].get_category_children(category_id, **generate_api_kwargs(args)))) | ||
except (ValueError, BaseFredAPIError) as e: | ||
raise click.UsageError(click.style(e, fg="red"), ctx) | ||
|
||
|
||
@categories.command() | ||
@click.option("--category-id", "-i", required=True, type=click.STRING, help="Category ID.") | ||
@click.argument("args", nargs=-1) | ||
@click.pass_context | ||
def get_category_related(ctx, category_id: int, args: tuple): | ||
"""Get related categories.""" | ||
try: | ||
click.echo(serialize(ctx.obj["client"].get_category_related(category_id, **generate_api_kwargs(args)))) | ||
except (ValueError, BaseFredAPIError) as e: | ||
raise click.UsageError(click.style(e, fg="red"), ctx) | ||
|
||
|
||
@categories.command() | ||
@click.option("--category-id", "-i", required=True, type=click.STRING, help="Category ID.") | ||
@click.argument("args", nargs=-1) | ||
@click.pass_context | ||
def get_category_series(ctx, category_id: int, args: tuple): | ||
"""Get series in a category.""" | ||
try: | ||
click.echo(serialize(ctx.obj["client"].get_category_series(category_id, **generate_api_kwargs(args)))) | ||
except (ValueError, BaseFredAPIError) as e: | ||
raise click.UsageError(click.style(e, fg="red"), ctx) | ||
|
||
|
||
@categories.command() | ||
@click.option("--category-id", "-i", required=True, type=click.STRING, help="Category ID.") | ||
@click.argument("args", nargs=-1) | ||
@click.pass_context | ||
def get_category_tags(ctx, category_id: int, args: tuple): | ||
"""Get FRED tags for a category.""" | ||
try: | ||
click.echo(serialize(ctx.obj["client"].get_category_tags(category_id, **generate_api_kwargs(args)))) | ||
except (ValueError, BaseFredAPIError) as e: | ||
raise click.UsageError(click.style(e, fg="red"), ctx) | ||
|
||
|
||
@categories.command() | ||
@click.option("--category-id", "-i", required=True, type=click.STRING, help="Category ID.") | ||
@click.option("--tag-names", "-t", required=True, type=click.STRING, help="Tag Names.") | ||
@click.argument("args", nargs=-1) | ||
@click.pass_context | ||
def get_category_related_tags(ctx, category_id: int, tag_names: str, args: tuple): | ||
"""Get related FRED tags for a category.""" | ||
try: | ||
click.echo( | ||
serialize(ctx.obj["client"].get_category_related_tags(category_id, tag_names, **generate_api_kwargs(args))) | ||
) | ||
except (ValueError, BaseFredAPIError) as e: | ||
raise click.UsageError(click.style(e, fg="red"), ctx) |
Oops, something went wrong.