pygarden


Namepygarden JSON
Version 0.3.23 PyPI version JSON
download
home_pageNone
SummaryPackage to perform everyday tasks - logging, accessing database, etc.
upload_time2025-07-31 18:35:11
maintainerNone
docs_urlNone
authorAlec Hamaker
requires_python<3.13,>=3.10
licenseCopyright 2021 ORNL Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords database logging mixins mysqlmixin pandasmixin postgresmixin
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # pyGARDEN Package

Code for the pyGARDEN (**G**eneral **A**pplication **R**esource **D**evelopment **E**nvironment **N**etwork) Python Package to include easy injectable and rich logging, environment checking, and database
connections and query. By default, only SQLite is available as a mixin, but other mixin types to the `Database` class
are Postgres (`[postgres]` extra) or Microsoft SQL Server (`[mssql]` extra). See the [extras](#Extras) section for more
information on how to install these extras, when to choose them, and how to use them.
Some highlights from `pyGARDEN`:

- This package contains an extensible `Database` metaclass with a generic query function that is usable out of the box.
- Everything is configurable with environmental variables -- including email sending, logging, and database connections.

## Installation

### Installation via `uv`

If you have a `uv venv`, you can run the following command in the root of the repo:

`uv pip install -e ".[dev,cli,postgres]"`

You may then need to source your `uv` environment to use the `pygarden` command line interface, e.g. `source .venv/bin/activate`.

Replace the above extras with the extras of your choice.

## Extras

To enable support for specific databases, use the following extras:

- `postgres`: Enables Postgres support via `psycopg2`
- `mssql`: Enables MSSQL support via `pymssql`

#### `pymssql` on MacOS

Before install the `mssql` extra, you may need to install `freetds` using `brew`:

```bash
brew install freetds openssl@3.0
export LDFLAGS="-L/opt/homebrew/opt/freetds/lib -L/opt/homebrew/opt/openssl@3.0/lib"
export CPPFLAGS="-I/opt/homebrew/opt/freetds/include -I/opt/homebrew/opt/openssl@3.0/include"
export PKG_CONFIG_PATH="/opt/homebrew/opt/openssl@3.0/lib/pkgconfig"
```

Then, install `pymssql` to your uv environment on its own using:

```bash
uv pip install pymssql==2.2.11 --no-binary :all:
```

After than, you can run `uv sync --extra mssql` or `uv sync --extra all` to get the rest of the dependencies in the group.

### Installation via pip

Run this command to install version 0.3.23 (latest) via pip:

`python3 -m pip --no-cache-dir install pygarden==0.3.23`

This will install latest (not recommended):

`python3 -m pip --no-cache-dir install pygarden`

## Getting the Image

The Docker image for this project is hosted on [Savannah](https://savannah.ornl.gov/),
and is tagged with `savannah.ornl.gov/common/pygarden:${PYTHON_VERSION:-3.12}-latest`,
where `${PYTHON_VERSION:-3.12}` is the Python version you want to use. To pull the
image, you can run:

```bash
docker pull savannah.ornl.gov/common/pygarden:${PYTHON_VERSION:-3.12}-latest
```

## Saving the Image to a Tar File

If you want to save the image to a tar file, you can run:

```bash
docker save savannah.ornl.gov/common/pygarden:${PYTHON_VERSION:-3.12}-latest -o pygarden.tar
gzip pygarden.tar  # optionally compress the tar file
```

Now you can transport the image wherever you'd like!

### Configuration via Environment Variables

Below is a list of environmental variables and what they do:

- DATABASE_TIMEOUT, PG_TIMEOUT: an integer representing the seconds to wait before deciding a timeout occurred.
- DATABASE_DB, PG_DATABASE: a string representing the database to connect to
- DATABASE_USER, PG_USER: a string representing the user to connect to the database as
- DATABASE_PW, PG_PASSWORD: a string representing the password for the DATABASE_USER
- DATABASE_HOST, PG_HOST: a string representing the hostname or IP address hosting the database
- DATABASE_PORT, PG_PORT: an integer representing the port to connect to the database on
- DATABASE_SCHEMA, PG_SCHEMA: a string representing the schema to default to when creating a database connection

These environmental variables have been assigned default values for the Docker container in the file `envfile`, which is called in `docker-compose.yaml` and `docker-compose.test.yaml`

### Creating an extensible Database Python Class

Some `Database` methods such as `query` and `open` rely on
[python mixins](https://www.python.org/dev/peps/pep-0487/), which allow
abstract classes to interact with different types of databases and provide
additional functionality not provided by the `Database` class. Below is an
example of how to create a Database class that uses the PostgresMixin:

```python
from pygarden.mixins.postgres import PostgresMixin
from pygarden.database import Database


class PostgresDatabase(Database, PostgresMixin):
    """The class that allows Database to interact with psycopg2."""
    # TODO add additional functions for your class here, specific to your needs

with PostgresDatabase() as db:
    db.query('SELECT NOW()')
```

### Creating a CRUD table with crud_table.py

```python
from pygarden.mixins.postgres import PostgresMixin
from pygarden.database import Database
from pygarden.crud_table import CRUDTable

# PLEASE NOTE: the name of class MUST be consistent with the name of the
# table in the database itself.
class Users(CRUDTable):
    """Provides CRUD access to the users table"""
    def __init__(self, db):
    """__init__:

    :param db: the database that contains the 'users' table.
    """
    # be sure to define the columns as they appear in the database.
    # in this example, the users table has 6 columns.
    columns = {
        'id': int,
        'email': str,
        'password': str,
    }
    # initialize the super class with the column definition, the schema that
    # the table is in, and the database object.
    super().__init__(columns, schema='public', db)

    # TODO add additional functions for your class here, specific to your needs


class PostgresDatabase(Database, PostgresMixin):
    """The class that allows Database to interact with psycopg2."""
    def __init__(self):
        super().__init__()
        # here we are assigning the CRUD table to the database's 'users'
        # variable and passing the database object to the constructor
        self.users = users(self)
    # TODO add additional functions for your class here, specific to your needs

with PostgresDatabase() as db:
    db.query('SELECT NOW()')

    # this will create a user in the database, with the specified fields and
    # null for the columns not specified
    db.users.create(id=1337, email='admin@test.com', password='*****')

    # this will read the entire user's table 'SELECT * FROM public.users;'
    users_table = db.users.read()

    # this will read only id, and email columns from the users table
    # 'SELECT id, email FROM public.users;'
    columns_users_table = db.users.read(columns=['id', 'email'])

    # data can be read from the database in 'json' format by specifying
    # json=True in your call. The 'json' format returned is a python dictionary
    # that is json serializable
    json_data = db.users.read(json=True)

    # where clauses can be passed as keyword arguments to the call
    # 'SELECT * FROM public.users WHERE id = 1337;
    filtered_users_table = db.users.read(id=1337)

    # to update entries, a where clause must be passed as follows
    # 'UPDATE public.users SET email='update@test.com' WHERE id=1337;'
    db.users.update(where={'id': 1337}, email='update@test.com')

    # to delete entries, a where clause must also be passed. The where clause
    # for a deletion should come in the form of keyword arguments
    # 'DELETE FROM public.users WHERE id=1337;'
    db.users.delete(id=1337)
```

## Testing

The tests for `pygarden` use `pytest` and are available in the `dev` extra.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "pygarden",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<3.13,>=3.10",
    "maintainer_email": null,
    "keywords": "database, logging, mixins, mysqlmixin, pandasmixin, postgresmixin",
    "author": "Alec Hamaker",
    "author_email": "\"Grant, Josh\" <grantjn@ornl.gov>, Jonathan Huihui <huihuijk@ornl.gov>, Bhaskar Bishnoi <bishnoib@ornl.gov>, Kyle Medlen <medlenwk@ornl.gov>, Midgie MacFarland <macfarlandmj@ornl.gov>, Chris Tester <testercb@ornl.gov>, Jacob Isber <isberj@ornl.gov>, Mitchell Broughton <broxsonmr@ornl.gov>",
    "download_url": "https://files.pythonhosted.org/packages/14/4f/984c2d7038d9b6d4f1478f9cfc9a0667fc76586165ee90b520d744606d5a/pygarden-0.3.23.tar.gz",
    "platform": null,
    "description": "# pyGARDEN Package\n\nCode for the pyGARDEN (**G**eneral **A**pplication **R**esource **D**evelopment **E**nvironment **N**etwork) Python Package to include easy injectable and rich logging, environment checking, and database\nconnections and query. By default, only SQLite is available as a mixin, but other mixin types to the `Database` class\nare Postgres (`[postgres]` extra) or Microsoft SQL Server (`[mssql]` extra). See the [extras](#Extras) section for more\ninformation on how to install these extras, when to choose them, and how to use them.\nSome highlights from `pyGARDEN`:\n\n- This package contains an extensible `Database` metaclass with a generic query function that is usable out of the box.\n- Everything is configurable with environmental variables -- including email sending, logging, and database connections.\n\n## Installation\n\n### Installation via `uv`\n\nIf you have a `uv venv`, you can run the following command in the root of the repo:\n\n`uv pip install -e \".[dev,cli,postgres]\"`\n\nYou may then need to source your `uv` environment to use the `pygarden` command line interface, e.g. `source .venv/bin/activate`.\n\nReplace the above extras with the extras of your choice.\n\n## Extras\n\nTo enable support for specific databases, use the following extras:\n\n- `postgres`: Enables Postgres support via `psycopg2`\n- `mssql`: Enables MSSQL support via `pymssql`\n\n#### `pymssql` on MacOS\n\nBefore install the `mssql` extra, you may need to install `freetds` using `brew`:\n\n```bash\nbrew install freetds openssl@3.0\nexport LDFLAGS=\"-L/opt/homebrew/opt/freetds/lib -L/opt/homebrew/opt/openssl@3.0/lib\"\nexport CPPFLAGS=\"-I/opt/homebrew/opt/freetds/include -I/opt/homebrew/opt/openssl@3.0/include\"\nexport PKG_CONFIG_PATH=\"/opt/homebrew/opt/openssl@3.0/lib/pkgconfig\"\n```\n\nThen, install `pymssql` to your uv environment on its own using:\n\n```bash\nuv pip install pymssql==2.2.11 --no-binary :all:\n```\n\nAfter than, you can run `uv sync --extra mssql` or `uv sync --extra all` to get the rest of the dependencies in the group.\n\n### Installation via pip\n\nRun this command to install version 0.3.23 (latest) via pip:\n\n`python3 -m pip --no-cache-dir install pygarden==0.3.23`\n\nThis will install latest (not recommended):\n\n`python3 -m pip --no-cache-dir install pygarden`\n\n## Getting the Image\n\nThe Docker image for this project is hosted on [Savannah](https://savannah.ornl.gov/),\nand is tagged with `savannah.ornl.gov/common/pygarden:${PYTHON_VERSION:-3.12}-latest`,\nwhere `${PYTHON_VERSION:-3.12}` is the Python version you want to use. To pull the\nimage, you can run:\n\n```bash\ndocker pull savannah.ornl.gov/common/pygarden:${PYTHON_VERSION:-3.12}-latest\n```\n\n## Saving the Image to a Tar File\n\nIf you want to save the image to a tar file, you can run:\n\n```bash\ndocker save savannah.ornl.gov/common/pygarden:${PYTHON_VERSION:-3.12}-latest -o pygarden.tar\ngzip pygarden.tar  # optionally compress the tar file\n```\n\nNow you can transport the image wherever you'd like!\n\n### Configuration via Environment Variables\n\nBelow is a list of environmental variables and what they do:\n\n- DATABASE_TIMEOUT, PG_TIMEOUT: an integer representing the seconds to wait before deciding a timeout occurred.\n- DATABASE_DB, PG_DATABASE: a string representing the database to connect to\n- DATABASE_USER, PG_USER: a string representing the user to connect to the database as\n- DATABASE_PW, PG_PASSWORD: a string representing the password for the DATABASE_USER\n- DATABASE_HOST, PG_HOST: a string representing the hostname or IP address hosting the database\n- DATABASE_PORT, PG_PORT: an integer representing the port to connect to the database on\n- DATABASE_SCHEMA, PG_SCHEMA: a string representing the schema to default to when creating a database connection\n\nThese environmental variables have been assigned default values for the Docker container in the file `envfile`, which is called in `docker-compose.yaml` and `docker-compose.test.yaml`\n\n### Creating an extensible Database Python Class\n\nSome `Database` methods such as `query` and `open` rely on\n[python mixins](https://www.python.org/dev/peps/pep-0487/), which allow\nabstract classes to interact with different types of databases and provide\nadditional functionality not provided by the `Database` class. Below is an\nexample of how to create a Database class that uses the PostgresMixin:\n\n```python\nfrom pygarden.mixins.postgres import PostgresMixin\nfrom pygarden.database import Database\n\n\nclass PostgresDatabase(Database, PostgresMixin):\n    \"\"\"The class that allows Database to interact with psycopg2.\"\"\"\n    # TODO add additional functions for your class here, specific to your needs\n\nwith PostgresDatabase() as db:\n    db.query('SELECT NOW()')\n```\n\n### Creating a CRUD table with crud_table.py\n\n```python\nfrom pygarden.mixins.postgres import PostgresMixin\nfrom pygarden.database import Database\nfrom pygarden.crud_table import CRUDTable\n\n# PLEASE NOTE: the name of class MUST be consistent with the name of the\n# table in the database itself.\nclass Users(CRUDTable):\n    \"\"\"Provides CRUD access to the users table\"\"\"\n    def __init__(self, db):\n    \"\"\"__init__:\n\n    :param db: the database that contains the 'users' table.\n    \"\"\"\n    # be sure to define the columns as they appear in the database.\n    # in this example, the users table has 6 columns.\n    columns = {\n        'id': int,\n        'email': str,\n        'password': str,\n    }\n    # initialize the super class with the column definition, the schema that\n    # the table is in, and the database object.\n    super().__init__(columns, schema='public', db)\n\n    # TODO add additional functions for your class here, specific to your needs\n\n\nclass PostgresDatabase(Database, PostgresMixin):\n    \"\"\"The class that allows Database to interact with psycopg2.\"\"\"\n    def __init__(self):\n        super().__init__()\n        # here we are assigning the CRUD table to the database's 'users'\n        # variable and passing the database object to the constructor\n        self.users = users(self)\n    # TODO add additional functions for your class here, specific to your needs\n\nwith PostgresDatabase() as db:\n    db.query('SELECT NOW()')\n\n    # this will create a user in the database, with the specified fields and\n    # null for the columns not specified\n    db.users.create(id=1337, email='admin@test.com', password='*****')\n\n    # this will read the entire user's table 'SELECT * FROM public.users;'\n    users_table = db.users.read()\n\n    # this will read only id, and email columns from the users table\n    # 'SELECT id, email FROM public.users;'\n    columns_users_table = db.users.read(columns=['id', 'email'])\n\n    # data can be read from the database in 'json' format by specifying\n    # json=True in your call. The 'json' format returned is a python dictionary\n    # that is json serializable\n    json_data = db.users.read(json=True)\n\n    # where clauses can be passed as keyword arguments to the call\n    # 'SELECT * FROM public.users WHERE id = 1337;\n    filtered_users_table = db.users.read(id=1337)\n\n    # to update entries, a where clause must be passed as follows\n    # 'UPDATE public.users SET email='update@test.com' WHERE id=1337;'\n    db.users.update(where={'id': 1337}, email='update@test.com')\n\n    # to delete entries, a where clause must also be passed. The where clause\n    # for a deletion should come in the form of keyword arguments\n    # 'DELETE FROM public.users WHERE id=1337;'\n    db.users.delete(id=1337)\n```\n\n## Testing\n\nThe tests for `pygarden` use `pytest` and are available in the `dev` extra.\n",
    "bugtrack_url": null,
    "license": "Copyright 2021 ORNL  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in  the Software without restriction, including without limitation the rights to  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies  of the Software, and to permit persons to whom the Software is furnished to do  so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  SOFTWARE.",
    "summary": "Package to perform everyday tasks - logging, accessing database, etc.",
    "version": "0.3.23",
    "project_urls": {
        "Source": "https://code.ornl.gov/pygarden/pygarden"
    },
    "split_keywords": [
        "database",
        " logging",
        " mixins",
        " mysqlmixin",
        " pandasmixin",
        " postgresmixin"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "b2f8534456bfa1761279359fe165adbebcc556e7567a0179a9b8d62a3c28482e",
                "md5": "56de82c6d62a9660a1f60d0a26397a72",
                "sha256": "f105dc51b48974a41972d1da1a3f8a212ba7f4720ffeb52b64cc5cef64a1a181"
            },
            "downloads": -1,
            "filename": "pygarden-0.3.23-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "56de82c6d62a9660a1f60d0a26397a72",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<3.13,>=3.10",
            "size": 63982,
            "upload_time": "2025-07-31T18:35:10",
            "upload_time_iso_8601": "2025-07-31T18:35:10.043216Z",
            "url": "https://files.pythonhosted.org/packages/b2/f8/534456bfa1761279359fe165adbebcc556e7567a0179a9b8d62a3c28482e/pygarden-0.3.23-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "144f984c2d7038d9b6d4f1478f9cfc9a0667fc76586165ee90b520d744606d5a",
                "md5": "de625e361473f7d297bfa8ca2af59d28",
                "sha256": "0ec64d6cd2d26805e323623ca97d3e3c9137673d2af5dedd6916eba73edf8cac"
            },
            "downloads": -1,
            "filename": "pygarden-0.3.23.tar.gz",
            "has_sig": false,
            "md5_digest": "de625e361473f7d297bfa8ca2af59d28",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<3.13,>=3.10",
            "size": 114332,
            "upload_time": "2025-07-31T18:35:11",
            "upload_time_iso_8601": "2025-07-31T18:35:11.236291Z",
            "url": "https://files.pythonhosted.org/packages/14/4f/984c2d7038d9b6d4f1478f9cfc9a0667fc76586165ee90b520d744606d5a/pygarden-0.3.23.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-31 18:35:11",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "pygarden"
}
        
Elapsed time: 1.25063s