Skip to content
This repository has been archived by the owner on Jul 13, 2022. It is now read-only.

Commit

Permalink
Changed DBInfo interface and updated README (#13)
Browse files Browse the repository at this point in the history
* Changed DBInfo interface and updated README

* Version bumped to 0.14.0

* Update cruft

* comment out flake8 issues

* Fix DBInfo references for test

* PR comments

* typos

Co-authored-by: ns-circle-ci <[email protected]>
  • Loading branch information
RJ Santana and ns-circle-ci authored Oct 19, 2021
1 parent 9f2cb8a commit bcf0ca1
Show file tree
Hide file tree
Showing 23 changed files with 239 additions and 48 deletions.
11 changes: 11 additions & 0 deletions .circleci/commands/restore-test-cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
description: Restores the build-test cache for pyenv, poetry, and pre-commit
steps:
- restore_cache:
keys:
- v2-pyenv-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
- restore_cache:
keys:
- v2-poetry-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
- restore_cache:
keys:
- v2-precommit-{{ arch }}-pynocular-{{ checksum ".pre-commit-config.yaml" }}
14 changes: 14 additions & 0 deletions .circleci/commands/save-test-cache.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
description: Stores the build-test cache for pyenv, poetry, and pre-commit
steps:
- save_cache:
key: v2-pyenv-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
paths:
- "~/.pyenv"
- save_cache:
key: v2-poetry-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
paths:
- "~/.cache/pypoetry"
- save_cache:
key: v2-precommit-{{ arch }}-pynocular-{{ checksum ".pre-commit-config.yaml" }}
paths:
- "~/.cache/pre-commit"
22 changes: 22 additions & 0 deletions .circleci/commands/store-test-artifacts.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
description: Store test artifacts in CCI workflow run
parameters:
artifacts_path:
description: The absolute path to the artifacts stored as an env var
type: string
artifacts_storage_dir:
description: The directory in /tmp where we want to store the artifacts
type: string
default: << parameters.artifacts_path >>
export_test_results:
description: Whether or not to upload the artifacts as Test Summary metadata
type: boolean
default: false
steps:
- store_artifacts:
path: << parameters.artifacts_path >>
destination: << parameters.artifacts_storage_dir >>
- when:
condition: << parameters.export_test_results >>
steps:
- store_test_results:
path: << parameters.artifacts_path >>
79 changes: 73 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,60 @@ commands:
pip install poetry
poetry config pypi-token.pypi "$POETRY_PYPI_TOKEN_PYPI"
name: Configure Poetry
restore-test-cache:
description: Restores the build-test cache for pyenv, poetry, and pre-commit
steps:
- restore_cache:
keys:
- v2-pyenv-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
- restore_cache:
keys:
- v2-poetry-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
- restore_cache:
keys:
- v2-precommit-{{ arch }}-pynocular-{{ checksum ".pre-commit-config.yaml" }}
save-test-cache:
description: Stores the build-test cache for pyenv, poetry, and pre-commit
steps:
- save_cache:
key: v2-pyenv-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
paths:
- ~/.pyenv
- save_cache:
key: v2-poetry-{{ arch }}-pynocular-{{ checksum "poetry.lock" }}
paths:
- ~/.cache/pypoetry
- save_cache:
key: v2-precommit-{{ arch }}-pynocular-{{ checksum ".pre-commit-config.yaml" }}
paths:
- ~/.cache/pre-commit
store-test-artifacts:
description: Store test artifacts in CCI workflow run
parameters:
artifacts_path:
description: The absolute path to the artifacts stored as an env var
type: string
artifacts_storage_dir:
default: << parameters.artifacts_path >>
description: The directory in /tmp where we want to store the artifacts
type: string
export_test_results:
default: false
description: Whether or not to upload the artifacts as Test Summary metadata
type: boolean
steps:
- store_artifacts:
destination: << parameters.artifacts_storage_dir >>
path: << parameters.artifacts_path >>
- when:
condition: << parameters.export_test_results >>
steps:
- store_test_results:
path: << parameters.artifacts_path >>
executors:
default:
docker:
- image: cimg/python:3.6
- image: cimg/python:3.9
resource_class: small
python-3_6-medium:
docker:
Expand Down Expand Up @@ -291,6 +341,7 @@ jobs:
- ghpr/build-prospective-branch
- aws-cli/install
- circleci-cli/install
- restore-test-cache
- poetry-configure
- bump-branch-version
- run:
Expand All @@ -310,11 +361,19 @@ jobs:
--origin "origin/${CIRCLE_BRANCH}" \
--show-diff-on-failure
name: Run commit hooks
- run: poetry run pytest --junit-xml .junit/unit/results.xml
- store_test_results:
path: .junit
- ghpr/post-pr-comment:
comment: Tests failed!
- run:
command: |
mkdir -p test-results/unit
poetry run pytest --junit-xml test-results/unit/results.xml
name: Run tests
- store-test-artifacts:
artifacts_path: test-results
export_test_results: true
- save-test-cache
- ghpr/slack-pr-author:
color: '#fcaaa3'
get_slack_user_by: meseeks
message: ':ci-fail: Tests failed'
when: on_fail
poetry-publish:
description: Publish a release of the project
Expand All @@ -328,6 +387,14 @@ jobs:
- run: poetry install
- run: poetry build
- run: poetry publish
send-slack-on-pr-success:
description: Send a Slack message to the PR author on PR workflow success.
executor: default
steps:
- ghpr/slack-pr-author:
color: '#4cb79c'
get_slack_user_by: meseeks
message: ':ci-success: PR tests have passed!'
orbs:
aws-cli: circleci/[email protected]
circleci-cli: circleci/[email protected]
Expand Down
2 changes: 1 addition & 1 deletion .circleci/executors/default.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
docker:
- image: cimg/python:3.6
- image: cimg/python:3.9
resource_class: small
19 changes: 14 additions & 5 deletions .circleci/jobs/build-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ steps:
- ghpr/build-prospective-branch
- aws-cli/install
- circleci-cli/install
- restore-test-cache
- poetry-configure
- bump-branch-version
- run:
Expand All @@ -32,9 +33,17 @@ steps:
--source "origin/${GITHUB_PR_BASE_BRANCH}" \
--origin "origin/${CIRCLE_BRANCH}" \
--show-diff-on-failure
- run: poetry run pytest --junit-xml .junit/unit/results.xml
- store_test_results:
path: .junit
- ghpr/post-pr-comment:
comment: Tests failed!
- run:
name: Run tests
command: |
mkdir -p test-results/unit
poetry run pytest --junit-xml test-results/unit/results.xml
- store-test-artifacts:
artifacts_path: test-results
export_test_results: true
- save-test-cache
- ghpr/slack-pr-author:
when: on_fail
message: ':ci-fail: Tests failed'
get_slack_user_by: meseeks
color: "#fcaaa3"
7 changes: 7 additions & 0 deletions .circleci/jobs/send-slack-on-pr-success.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
description: Send a Slack message to the PR author on PR workflow success.
executor: default
steps:
- ghpr/slack-pr-author:
message: ':ci-success: PR tests have passed!'
get_slack_user_by: meseeks
color: "#4cb79c"
2 changes: 1 addition & 1 deletion .cruft.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"template": "https://github.com/NarrativeScience/cookiecutter-python-lib",
"commit": "c0344678b29ccb03a7775bed55a202a8453161ee",
"commit": "9e14f244710d27b6ddf3f6a88e107488b7d3208e",
"context": {
"cookiecutter": {
"package_name": "pynocular",
Expand Down
8 changes: 8 additions & 0 deletions .githooks/pre-commit-scripts/cruft-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash

# Run the cruft check and if it fails prompt user to run the manual update
cruft check
if [[ $? -ne 0 ]]; then
echo "This project's cruft is not up to date."
echo "Please run 'cruft update' and follow the prompts to update this repository."
fi
16 changes: 12 additions & 4 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,21 @@ repos:
entry: isort
language: python
types: [file, python]
additional_dependencies: [isort==4.3.16]
additional_dependencies: [isort==5.9.3]

- id: black
name: Format Python (black)
entry: black
language: python
types: [file, python]
additional_dependencies: [black==21.7b0]
additional_dependencies: [black==21.9b0]

- id: pydocstyle
name: Lint Python docstrings (pydocstyle)
entry: pydocstyle
language: python
types: [file, python]
additional_dependencies: [pydocstyle==5.0.2]
additional_dependencies: [pydocstyle==6.1.1]
exclude: >
(?x)^(
.*__init__.py$|
Expand All @@ -76,7 +76,7 @@ repos:
language: python
types: [file, python]
additional_dependencies:
- flake8==3.7.9
- flake8==3.9.2
- "flake8-import-order<0.19,>=0.18"
- flake8-print>=3.1.4,<4

Expand All @@ -85,3 +85,11 @@ repos:
entry: .githooks/pre-commit-scripts/circleci.sh
language: script
files: '^\.circleci/'

- id: cruft-check
name: Check project's Cruft (Cruft)
entry: .githooks/pre-commit-scripts/cruft-check.sh
language: python
additional_dependencies: [cruft==2.9.0]
always_run: true
stages: [push]
2 changes: 2 additions & 0 deletions CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# See: https://help.github.com/en/articles/about-code-owners
* @ssantana-ns @jdrake
32 changes: 24 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# pynocular
# Pynocular

[![](https://img.shields.io/pypi/v/pynocular.svg)](https://pypi.org/pypi/pynocular/) [![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)

Expand Down Expand Up @@ -27,7 +27,7 @@ Table of Contents:

## Installation

pynocular requires Python 3.6 or above.
Pynocular requires Python 3.6 or above.

```bash
pip install pynocular
Expand All @@ -51,11 +51,15 @@ from pynocular.engines import DatabaseType, DBInfo
# Example below shows how to connect to a locally-running Postgres database
connection_string = f"postgresql://{db_user_name}:{db_user_password}@localhost:5432/{db_name}?sslmode=disable"
)
db_info = DBInfo(DatabaseType.aiopg_engine, connection_string)
db_info = DBInfo(connection_string)
```

Pynocular supports connecting to your database through two different asyncio engines; aiopg and asyncpgsa.
You can pick which one you want to use by passing the correct `DatabaseType` enum value into `DBInfo`.
Pynocular uses the asynchronous engine provided by aiopg to connect to your database. You can choose to use a
different engine by providing a different engine_type value to `DBInfo`.
```python
db_info = DBInfo(connection_string, engine_type=DatabaseAlias.asyncpg_engine)
```
All other engine options are experimental and do not support all of the functionality Pynocular provides.

#### Object Management

Expand Down Expand Up @@ -404,7 +408,7 @@ await create_table(db_info, Org._table)
Pynocular comes with tooling to write unit tests against your DatabaseModels, giving you
the ability to test your business logic without the extra work and latency involved in
managing a database. All you have to do is use the `patch_database_model` context
manager provided in pynocular.
manager provided in Pynocular.

```python
from pynocular.patch_models import patch_database_model
Expand Down Expand Up @@ -455,15 +459,27 @@ with patch_database_model(Org, models=orgs), patch_database_model(

## Development

To develop pynocular, install dependencies and enable the pre-commit hook:
To develop Pynocular, install dependencies and enable the pre-commit hook.

The example below is using Python 3.9 but you can replace this with any supported version of Python.

Install Python 3.9 and activate it in your shell.

```bash
sudo yum install libffi-devel # Needed for ctypes to install poetry
pyenv install 3.9.7
pyenv shell 3.9.7
```

Install dependencies and enable the pre-commit hook.

```bash
pip install pre-commit poetry
poetry install
pre-commit install
```

To run tests:
Run tests to confirm everything is installed correctly.

```bash
poetry run pytest
Expand Down
19 changes: 19 additions & 0 deletions pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Overview of changes
*Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.*

*Please indicate the type of change: bug(fix), new feature, tests, config/infrastructure, docs, etc.*
*Be sure to link to that issue and place it in the name of the PR.*

## For software test
*Describe any pertinent instructions to get this running or vulnerable test areas.*

## Additional details
* additional notes, things that were changed, areas of concern, etc.*

## Important Reminders
- We like PRs to be less than 300 LOC
- Run the pre-commit for both hook stages! (pre-commit and pre-push)
- Add tests! Do not forget that we use pytest here at Narrative Science. 80% Code Coverage recommended.
- Use proper mocks in tests. Do not write tests without mocks that test external libraries or external endpoints.
- Add necessary documentation to README's
- Notion page with our detailed [PR guidelines](https://www.notion.so/narsci/Code-Reviews-fc8109101b2144739a7d9cde1fe2248b)
2 changes: 1 addition & 1 deletion pynocular/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Lightweight ORM that lets you query your database using Pydantic models and asyncio"""

__version__ = "0.13.0"
__version__ = "0.14.0"

from pynocular.engines import DatabaseType, DBInfo
4 changes: 2 additions & 2 deletions pynocular/db_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import sqlalchemy as sa
from sqlalchemy.sql.ddl import CreateTable

from pynocular.engines import DatabaseType, DBEngine, DBInfo
from pynocular.engines import DBEngine, DBInfo
from pynocular.exceptions import InvalidSqlIdentifierErr

logger = logging.getLogger()
Expand Down Expand Up @@ -43,7 +43,7 @@ async def create_new_database(connection_string: str, db_name: str) -> None:
db_name: the name of the database to create
"""
existing_db = DBInfo(DatabaseType.aiopg_engine, connection_string)
existing_db = DBInfo(connection_string)
conn = await (await DBEngine.get_engine(existing_db)).acquire()
# End existing commit
await conn.execute("commit")
Expand Down
2 changes: 1 addition & 1 deletion pynocular/engines.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ class DatabaseType(Enum):
class DBInfo(NamedTuple):
"""Data class for a database's connection information"""

engine_type: DatabaseType
connection_string: str
enable_hstore: bool = True
engine_type: DatabaseType = DatabaseType.aiopg_engine


class DBEngine:
Expand Down
Loading

0 comments on commit bcf0ca1

Please sign in to comment.