Skip to content
This repository has been archived by the owner on Feb 6, 2024. It is now read-only.

Commit

Permalink
Update project with initial application logic
Browse files Browse the repository at this point in the history
  • Loading branch information
nickviola committed Feb 2, 2022
1 parent 9192204 commit 6a286da
Show file tree
Hide file tree
Showing 29 changed files with 1,086 additions and 298 deletions.
44 changes: 22 additions & 22 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,33 @@ all of which should be in this repository.

If you want to report a bug or request a new feature, the most direct
method is to [create an
issue](https://github.com/cisagov/li-pca-app/issues) in
this repository. We recommend that you first search through existing
issue](https://github.com/cisagov/skeleton-generic/issues) in this
repository. We recommend that you first search through existing
issues (both open and closed) to check if your particular issue has
already been reported. If it has then you might want to add a comment
to the existing issue. If it hasn't then feel free to create a new
one.

## Branches ##

If you are a developer assigned to the PCA team, when creating a branch,
reference the corresponding ticket in JIRA as a prefix to the branch name.

For example: PCADEV-123_some_feature_branch

When pushing from your local repo to a remote, push first to your
remote branch and then create a pull request to merge back into develop.
Pushes directly to develop is not allowed.

## Pull requests ##

If you choose to [submit a pull
request](https://github.com/cisagov/li-pca-app/pulls),
you will notice that our continuous integration (CI) system runs a
fairly extensive set of linters, syntax checkers, system, and unit tests.
Your pull request may fail these checks, and that's OK. If you want
you can stop there and wait for us to make the necessary corrections
to ensure your code passes the CI checks.
request](https://github.com/cisagov/skeleton-generic/pulls), you will
notice that our continuous integration (CI) system runs a fairly
extensive set of linters and syntax checkers. Your pull request may
fail these checks, and that's OK. If you want you can stop there and
wait for us to make the necessary corrections to ensure your code
passes the CI checks.

If you want to make the changes yourself, or if you want to become a
regular contributor, then you will want to set up
Expand Down Expand Up @@ -135,9 +146,9 @@ can create and configure the Python virtual environment with these
commands:

```console
cd li-pca-app
pyenv virtualenv <python_version_to_use> li-pca-app
pyenv local li-pca-app
cd skeleton-generic
pyenv virtualenv <python_version_to_use> skeleton-generic
pyenv local skeleton-generic
pip install --requirement requirements-dev.txt
```

Expand All @@ -153,17 +164,6 @@ At this point the pre-commit checks will run against any files that
you attempt to commit. If you want to run the checks against the
entire repo, just execute `pre-commit run --all-files`.

### Running unit and system tests ###

In addition to the pre-commit checks the CI system will run the suite
of unit and system tests that are included with this project. To run
these tests locally execute `pytest` from the root of the project.

We encourage any updates to these tests to improve the overall code
coverage. If your pull request adds new functionality we would
appreciate it if you extend existing test cases, or add new ones to
exercise the newly added code.

## Public domain ##

This project is in the public domain within the United States, and
Expand Down
2 changes: 1 addition & 1 deletion bump_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ set -o nounset
set -o errexit
set -o pipefail

VERSION_FILE=src/example/_version.py
VERSION_FILE=src/api/_version.py

HELP_INFORMATION="bump_version.sh (show|major|minor|patch|prerelease|build|finalize)"

Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
--requirement requirements-test.txt
flask_testing
ipython
mypy
semver
1 change: 1 addition & 0 deletions requirements-test.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
--editable .[test]
--requirement requirements.txt
flask_testing
4 changes: 4 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Note: Add any additional requirements to setup.py's install_requires field
--editable .
connexion == 2.6.0
flask_testing
python_dateutil == 2.6.0
setuptools >= 21.0.0
wheel
2 changes: 1 addition & 1 deletion setup-env
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ for req_file in "requirements-dev.txt" "requirements-test.txt" "requirements.txt
done

# Install all necessary mypy type stubs
mypy --install-types src/
mypy --install-types --non-interactive

# Install git pre-commit hooks now or later.
pre-commit install ${INSTALL_HOOKS:+"--install-hooks"}
Expand Down
37 changes: 24 additions & 13 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""
This is the setup module for the example project.
This is the setup module for the li-pca-app api service.
Based on:
Expand All @@ -19,17 +19,17 @@

def readme():
"""Read in and return the contents of the project's README.md file."""
with open("README.md", encoding="utf-8") as f:
return f.read()
with open("README.md", encoding="utf-8") as in_file:
return in_file.read()


# Below two methods were pulled from:
# https://packaging.python.org/guides/single-sourcing-package-version/
def read(rel_path):
"""Open a file for reading from a given relative path."""
here = abspath(dirname(__file__))
with codecs.open(join(here, rel_path), "r") as fp:
return fp.read()
with codecs.open(join(here, rel_path), "r") as in_file:
return in_file.read()


def get_version(version_file):
Expand All @@ -42,10 +42,10 @@ def get_version(version_file):


setup(
name="example",
name="li-pca-api",
# Versions should comply with PEP440
version=get_version("src/example/_version.py"),
description="Example Python library",
version=get_version("src/api/_version.py"),
description="Li-PCA API",
long_description=readme(),
long_description_content_type="text/markdown",
# Landing page for CISA's cybersecurity mission
Expand Down Expand Up @@ -81,13 +81,19 @@ def get_version(version_file):
],
python_requires=">=3.6",
# What does your project relate to?
keywords="skeleton",
keywords="li-pca",
packages=find_packages(where="src"),
package_dir={"": "src"},
package_data={"example": ["data/*.txt"]},
package_data={"api": ["data/*.txt"]},
py_modules=[splitext(basename(path))[0] for path in glob("src/*.py")],
include_package_data=True,
install_requires=["docopt", "schema", "setuptools >= 24.2.0"],
install_requires=[
"docopt",
"schema",
"setuptools >= 24.2.0",
"connexion == 2.6.0",
"python_dateutil == 2.6.0",
],
extras_require={
"test": [
"coverage",
Expand All @@ -101,8 +107,13 @@ def get_version(version_file):
"pre-commit",
"pytest-cov",
"pytest",
"flask_testing",
]
},
# Conveniently allows one to run the CLI tool as `li-pca-api`
entry_points={
"console_scripts": [
"li-pca-api=api.__main__:main",
]
},
# Conveniently allows one to run the CLI tool as `example`
entry_points={"console_scripts": ["example = example.example:main"]},
)
Binary file added src/api/.Dockerfile.swp
Binary file not shown.
24 changes: 24 additions & 0 deletions src/api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""The example library."""
# We disable a Flake8 check for "Module imported but unused (F401)" because
# although this import is not directly used, it populates the value
# package_name.__version__, which is used to get version information about this
# Python package.
# cisagov Libraries
from api.controllers import customers_controller

from ._version import __version__ # noqa: F401

__all__ = [
"customers_controller",
# "api_response",
# "assessment",
# "base_model",
# "campaign",
# "customer",
# "document",
# "template",
# "user",
# "encoder",
# "type_util",
# "util"
]
20 changes: 20 additions & 0 deletions src/api/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/env python3
"""Code to run if this package is used as a Python module."""

# Third-Party Libraries
import connexion

# cisagov Libraries
from api import encoder


def main():
"""Run Main Application.."""
app = connexion.App(__name__, specification_dir="./openapi/")
app.app.json_encoder = encoder.JSONEncoder
app.add_api("openapi.yaml", arguments={"title": "Li-PCA API"}, pythonic_params=True)
app.run(port=8080)


if __name__ == "__main__":
main()
File renamed without changes.
1 change: 1 addition & 0 deletions src/api/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Controllers Init."""
88 changes: 88 additions & 0 deletions src/api/controllers/customers_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/usr/bin/env python
"""Customers Controller Logic."""

# Standard Python Libraries
import logging

# Third-Party Libraries
import connexion

# cisagov Libraries
# from api import util
from api.models.customer import Customer # noqa: E501


def create_customer(body=None): # noqa: E501
"""Add a new customer to the data store.
# noqa: E501
:param body: Customer object to be added to data store
:type body: dict | bytes
:rtype: None
"""
if connexion.request.is_json:
body = Customer.from_dict(connexion.request.get_json()) # noqa: E501
logging.debug("Body: %s", body)
return "do some magic!"


def delete_customer_by_uuid(uuid): # noqa: E501
"""Delete a customer.
# noqa: E501
:param uuid: uuid to delete
:type uuid: str
:rtype: None
"""
logging.debug("Uuid: %s", uuid)
return "do some magic!"


def get_all_customers(name=None): # noqa: E501
"""Find all customers.
Multiple status values can be provided with comma separated strings # noqa: E501
:param name: Customer name filter
:type name: List[str]
:rtype: List[Customer]
"""
logging.debug("name: %s", name)
return "do some magic!"


def get_customer_by_uuid(uuid): # noqa: E501
"""Find customer by uuid.
Returns a single customer # noqa: E501
:param uuid: uuid of customer to return
:type uuid: str
:rtype: Customer
"""
logging.debug("Uuid: %s", uuid)
return "do some magic!"


def update_customer_by_uuid(uuid, body=None): # noqa: E501
"""Update an existing customer.
# noqa: E501
:param uuid: uuid of customer to update
:type uuid: str
:param body: Customer object to be added to data store
:type body: dict | bytes
:rtype: None
"""
if connexion.request.is_json:
body = Customer.from_dict(connexion.request.get_json()) # noqa: E501
logging.debug("Body: %s", body)
return "do some magic!"
File renamed without changes.
37 changes: 37 additions & 0 deletions src/api/encoder.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
"""Encoding Utility Logic."""

# Third-Party Libraries
from connexion.apps.flask_app import FlaskJSONEncoder # type: ignore
import six # type: ignore

# cisagov Libraries
from api.models.base_model_ import Model


class JSONEncoder(FlaskJSONEncoder):
"""Encoding Class."""

include_nulls = False
encoding_type = "UTF-8"

def default(self, encode_target):
"""Use default encooding logic."""
if isinstance(encode_target, Model):
dikt = {}
for attr, _ in six.iteritems(encode_target.swagger_types):
value = getattr(encode_target, attr)
if value is None and not self.include_nulls:
continue
attr = encode_target.attribute_map[attr]
dikt[attr] = value
return dikt
return FlaskJSONEncoder.default(self, encode_target)

def set_decoding(self, encoding_type):
"""Set encooding type."""
# Raise assertion error if input type is invalid
# TODO: Check B101 allowance in bandit config
# assert isinstance(encoding_type, str)

self.encoding_type = encoding_type
return self.encoding_type
9 changes: 9 additions & 0 deletions src/api/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# coding: utf-8

# flake8: noqa
from __future__ import absolute_import

# cisagov Libraries
# import models into model package
from api.models.api_response import ApiResponse
from api.models.customer import Customer

0 comments on commit 6a286da

Please sign in to comment.