ckanext-flakes


Nameckanext-flakes JSON
Version 0.4.5 PyPI version JSON
download
home_pagehttps://github.com/DataShades/ckanext-flakes
Summary
upload_time2023-07-03 12:11:04
maintainer
docs_urlNone
authorSergey Motornyuk
requires_python
licenseAGPL
keywords ckan
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            [![Tests](https://github.com/DataShades/ckanext-flakes/workflows/Tests/badge.svg)](https://github.com/DataShades/ckanext-flakes/actions/workflows/test.yml)

# ckanext-flakes

Tools for creating and managing independent chunks of data.

This extension provides a base entity for storing arbitrary data. It can be
used in a number of cases, especially, if you don't want yet to create a brand
new model, database migrations and tables, but you have no other options.

`ckanext-flakes` gives you a set of actions for creating and managing small
dictionary-like objects(anything, that can be serialized into JSON). If you are
using it and want to add an extra action, feel free to create a PR or an issue
with your suggestion.

## Structure

* [Examples](#examples)
* [Example plugins](#example-plugins)
* [Requirements](#definition)
* [Installation](#installation)
* [Configuration](#configuration)
* [Interfaces](#interfaces)
* [API](#api)
  * [`flakes_flake_create`](#flakes_flake_create)
  * [`flakes_flake_show`](#flakes_flake_show)
  * [`flakes_flake_list`](#flakes_flake_list)
  * [`flakes_flake_update`](#flakes_flake_update)
  * [`flakes_flake_override`](#flakes_flake_override)
  * [`flakes_flake_delete`](#flakes_flake_delete)
  * [`flakes_flake_lookup`](#flakes_flake_lookup)
  * [`flakes_flake_validate`](#flakes_flake_validate)
  * [`flakes_data_validate`](#flakes_data_validate)
  * [`flakes_data_example`](#flakes_data_example)
  * [`flakes_flake_materialize`](#flakes_flake_materialize)
  * [`flakes_flake_combine`](#flakes_flake_combine)
  * [`flakes_flake_merge`](#flakes_flake_merge)
  * [`flakes_data_patch`](#flakes_data_patch)
  * [`flakes_extras_patch`](#flakes_extras_patch)

## Examples

### Create a collection of records

Scenario: user needs a todo list

Flakes created by any user are visible only to this user so flakes can be used
as a storage for private data.

Flakes can have `extras`, that plays a role of tags. `extras` represented by a
dictionary and whenever user lists his flakes, he has an option to see only
flakes that contains particular data inside extras.

```python
flake_create = tk.get_action("flakes_flake_create")
flake_list = tk.get_action("flakes_flake_create")

# create an urgent taks
flake_create(
    {"user": "john"},
    {"data": {"task": "feed the cat"}, "extras": {"when": "today", "type": "task"}}
)

# create a couple of tasks that can wait
flake_create(
    {"user": "john"},
    {"data": {"task": "buy food"}, "extras": {"when": "tomorrow", "type": "task"}}
)
flake_create(
    {"user": "john"},
    {"data": {"task": "update documentation"}, "extras": {"when": "tomorrow", "type": "task"}}
)

# list all the tasks
flake_list(
    {"user": "john"},
    {"extras": {"type": "task"}}
)

# list all the urgent tasks
flake_list(
    {"user": "john"},
    {"extras": {"type": "task", "when": "today"}}
)

# list all the tasks for tomorrow
flake_list(
    {"user": "john"},
    {"extras": {"type": "task", "when": "tomorrow"}}
)
```

### Save the value of the option individually for every user

Scenario: each user can set a theme of application and this theme will be applied only for the current user

Flakes are created for the user from the `context`. Flakes of the user A are
visible only to the user A, flakes of the user B exist in the different
namespace and are visible only to the user B.

Each flake **can** have a name. Name must be unique among the flakes of the
user. But different users can use the same names for their flakes, because
every user has its own namespace for flakes.

Flakes can be created either via `flakes_flake_create` action(accepts
**optional** name and raises exception if name is not unique) or
`flakes_flake_override`(requires a name and creates a new flake if name is not
taken or updates existing flake if name already used by some flake)

In order to get the flake use `flakes_flake_show` with the `id` of the flake or
`flakes_flake_lookup` with the `name`.

```python
# set a theme for John
tk.get_action("flakes_flake_override")(
    {"user": "john"},
    {"name": "application:theme", "data": {"theme": "dark"}}
)

# set a theme for Mary
tk.get_action("flakes_flake_override")(
    {"user": "mary"},
    {"name": "application:theme", "data": {"theme": "light"}}
)


# get the value from the flake
john_theme = tk.get_action("flakes_flake_lookup")(
    {"user": "john"},
    {"name": "application:theme"}
)["data"]["theme"]

mary_theme = tk.get_action("flakes_flake_lookup")(
    {"user": "mary"},
    {"name": "application:theme"}
)["data"]["theme"]

assert john_theme == "dark"
assert mary_theme == "light"
```

### Create and obtain global variable

Scenario: application requires global option, that can be changed in runtime

By default flakes are created in the "namespace" of the current user. Only the
author can see and modify his own flakes.

Global values should not be owned by someone, so here we need "unowned" flake -
the flake that is not connected to the particular user. Only sysadmin can
create such flakes, so we are going to use `ignore_auth=True` attribute of the
context.

We'll use `flakes_flake_override` action, that accepts a `name` of the flake
and either updates existing flakes with this name or creates a new one if this
name is free. In this way we'll avoid duplicates of the global flake.


```python
# create a flake
tk.get_action("flakes_flake_override")(
    {"ignore_auth": True}, # only syadmin allowed to create unowned flakes with empty author id
    {"name": "global:config:value", "data": {"value": 1}, "author_id": None}
)

# get the value from the flake
value = tk.get_action("flakes_flake_lookup")(
    {"ignore_auth": True},
    {"name": "global:config:value", "author_id": None}
)["data"]["value"]
```


## Example plugins

These plugins implement basic features that can be used as a real-life example
of `ckanext-flakes` usage.

### `flakes_rating`

User can rate a package via API action. Add
`ckanext.flakes_rating.show_package_widget = true` to the config and default
widget will be added to the sidebar on `dataset.read` page.

### `flakes_feedback`

User can leave a feedback for package via API action. Add
`ckanext.flakes_feedback.enable_views = true` to the config and default page
will be added to navigation tabs on `dataset.read` page.

## Requirements

Requires python v3.7 or greater. Python v2 support doesn't require much effort,
but it neither worth the time you'll spend on it.


Compatibility with core CKAN versions:

| CKAN version | Compatible? |
|--------------|-------------|
| 2.9          | yes         |
| 2.10         | yes         |


## Installation

To install ckanext-flakes:

1. Install it via **pip**:
   ```sh
   pip install ckanext-flakes
   ```
1. Add `flakes` to the `ckan.plugins` setting in your CKAN config file.
1. Run DB migrations:
   ```sh
   ckan db upgrade -p flakes
   ```

## Configuration

```ini
# Any user can create a new flake.
# (optional, default: true)
ckanext.flakes.creation.allowed = false

# Any user can validate flake or plain data.
# (optional, default: false)
ckanext.flakes.validation.allowed = true
```

## Interfaces

Provides `ckanext.flakes.interfaces.IFlakes` interface. Always use
`inherit=True` when implementing it, because it may change in the future.

Currently it provides the following hooks:

```python
class IFlakes(Interface):
    """Extend functionality of ckanext-flakes"""

    def get_flake_schemas(self) -> dict[str, dict[str, Any]]:
        """Register named validation schemas.

        Used by `flakes_flake_validate` and `flakes_data_validate` actions.

        Returns:
            Mapping of names and corresponding validation schemas.

        Example:
            def get_flake_schemas(self) -> dict[str, dict[str, Any]]:
                return {
                    "schema-that-requires-name": {"name": [not_missing]}
                }
        """
        return {}

    def get_flake_factories(self) -> dict[str, Callable[[dict[str, Any]], dict[str, Any]]]:
        """Register named example factories.

        Used by `flakes_data_example` action.

        Returns:
            Mapping of names and corresponding example factories.

        Example:
            def get_flake_factories(self) -> dict[str, dict[str, Any]]:
                def factory(payload: dict[str, Any]):
                    return {"field": "value"}

                return {
                    "test-factory": factory
                }
        """
        return {}
```


## API

### `flakes_flake_create`

Create a flake.

Args:

    name (str, optional): name of the flake
    data (dict): flake's data
    parent_id (str, optional): ID of flake to extend
    author_id (str, optional): author ID(can be set only by sysadmin)
    extras (dict): flake's extra details

### `flakes_flake_show`

Display existing flake

Args:

    id (str): ID of flake to display
    expand (bool, optional): Extend flake using data from the parent flakes


### `flakes_flake_list`

Display all flakes of the user.

If `extras` dictionary passed, show only flakes that contains given extras. Example:

    first_flake = Flake(extras={"xxx": {"yyy": "hello"}})
    second_flake = Flake(extras={"xxx": {"yyy": "world"}})

    flake_list(context, {"extras": {"xxx": {"yyy": "hello"}})
    >>> first_flake

Args:

    expand (bool, optional): Extend flake using data from the parent flakes
    extras (dict, optional): Show only flakes whose extras contains passed dict
    author_id (str, optional): author ID(can be set only by sysadmin)

### `flakes_flake_update`

Update existing flake

Args:

    id (str): ID of flake to update
    data (dict): flake's data
    parent_id (str, optional): ID of flake to extend
    extras (dict): flake's extra details

### `flakes_flake_override`

Update existing flake by name or create a new one.

Args:

    name (str): Name flake to override
    data (dict): template itself
    parent_id (str, optional): ID of flake to extend
    author_id (str, optional): author ID(can be set only by sysadmin if flake does not exist)
    extras (dict): flake's extra details

### `flakes_flake_delete`

Delete existing flake

Args:

    id (str): ID of flake to delete

### `flakes_flake_lookup`

Display flake using its name.

Args:

    name (str): Name of the flake
    expand (bool, optional): Extend flake using data from the parent flakes
    author_id (str, optional): author ID(can be set only by sysadmin)

### `flakes_flake_validate`

Validate existing flake

Schemas must be registered via `IFlakes` interface.

Args:

    id (str): ID of flake to validate
    expand (bool, optional): Extend flake using data from the parent flakes
    schema(str): validation schema for the flake's data


### `flakes_data_validate`

Validate arbitrary data against the named schema(registered via IFlakes).

Args:

    data (dict): data that needs to be validated
    schema(str): validation schema for the data

### `flakes_data_example`

Generate an example of the flake's data using named factory(registered via IFlakes).

Factories must be registered via `IFlakes` interface.

Args:

    factory(str): example factory
    data (dict, optional): payload for the example factory

### `flakes_flake_materialize`

Send flake's data to API action.

Args:

    id (str): ID of flake to materialize
    expand (bool, optional): Extend flake using data from the parent flakes
    remove (bool, optional): Remove flake after materialization
    action (str): API action to use for materialization

### `flakes_flake_combine`

Combine data from multiple flakes

`id` argument specifies all the flakes that must be combined. All of the flakes
must exist, otherwise `NotFound` error raised. IDs at the start of the list have
higher priority(override matching keys). IDs at the end of the list have lower
priority(can be shadowed by former flakes).

`expand` must be a `dict[str, bool]`. Keys are IDs of the flakes, values are
expand flags for the corresponding flake.

Args:

    id (list): IDs of flakes.
    expand (dict, optional): Extend flake using data from the parent flakes

### `flakes_flake_merge`

Combine multiple flakes and save the result.

Args:

    id (list): IDs of flakes.
    expand (dict, optional): Extend flake using data from the parent flakes
    remove (bool, optional): Remove flakes after the operation.
    destination (str, optional): Save data into the specified flake instead of a new one

### `flakes_data_patch`

Partially overrides data leaving other fields intact.

Args:

    id (str): ID of flake
    data (dict): patch for data


### `flakes_extras_patch`

Partially overrides extras leaving other fields intact.

Args:

    id (str): ID of flake
    extras (dict): patch for extras

## Developer installation

To install ckanext-flakes for development, activate your CKAN virtualenv and
do:

    git clone https://github.com/DataShades/ckanext-flakes.git
    cd ckanext-flakes
    python setup.py develop


## Tests

To run the tests, do:

    pytest

## License

[AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/DataShades/ckanext-flakes",
    "name": "ckanext-flakes",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "CKAN",
    "author": "Sergey Motornyuk",
    "author_email": "sergey.motornyuk@linkdigital.com.au",
    "download_url": "https://files.pythonhosted.org/packages/32/82/85ecc5e218d5ff4897b2268bec6bde8ba8bc2ad535d10291a2b4a413a1dd/ckanext-flakes-0.4.5.tar.gz",
    "platform": null,
    "description": "[![Tests](https://github.com/DataShades/ckanext-flakes/workflows/Tests/badge.svg)](https://github.com/DataShades/ckanext-flakes/actions/workflows/test.yml)\n\n# ckanext-flakes\n\nTools for creating and managing independent chunks of data.\n\nThis extension provides a base entity for storing arbitrary data. It can be\nused in a number of cases, especially, if you don't want yet to create a brand\nnew model, database migrations and tables, but you have no other options.\n\n`ckanext-flakes` gives you a set of actions for creating and managing small\ndictionary-like objects(anything, that can be serialized into JSON). If you are\nusing it and want to add an extra action, feel free to create a PR or an issue\nwith your suggestion.\n\n## Structure\n\n* [Examples](#examples)\n* [Example plugins](#example-plugins)\n* [Requirements](#definition)\n* [Installation](#installation)\n* [Configuration](#configuration)\n* [Interfaces](#interfaces)\n* [API](#api)\n  * [`flakes_flake_create`](#flakes_flake_create)\n  * [`flakes_flake_show`](#flakes_flake_show)\n  * [`flakes_flake_list`](#flakes_flake_list)\n  * [`flakes_flake_update`](#flakes_flake_update)\n  * [`flakes_flake_override`](#flakes_flake_override)\n  * [`flakes_flake_delete`](#flakes_flake_delete)\n  * [`flakes_flake_lookup`](#flakes_flake_lookup)\n  * [`flakes_flake_validate`](#flakes_flake_validate)\n  * [`flakes_data_validate`](#flakes_data_validate)\n  * [`flakes_data_example`](#flakes_data_example)\n  * [`flakes_flake_materialize`](#flakes_flake_materialize)\n  * [`flakes_flake_combine`](#flakes_flake_combine)\n  * [`flakes_flake_merge`](#flakes_flake_merge)\n  * [`flakes_data_patch`](#flakes_data_patch)\n  * [`flakes_extras_patch`](#flakes_extras_patch)\n\n## Examples\n\n### Create a collection of records\n\nScenario: user needs a todo list\n\nFlakes created by any user are visible only to this user so flakes can be used\nas a storage for private data.\n\nFlakes can have `extras`, that plays a role of tags. `extras` represented by a\ndictionary and whenever user lists his flakes, he has an option to see only\nflakes that contains particular data inside extras.\n\n```python\nflake_create = tk.get_action(\"flakes_flake_create\")\nflake_list = tk.get_action(\"flakes_flake_create\")\n\n# create an urgent taks\nflake_create(\n    {\"user\": \"john\"},\n    {\"data\": {\"task\": \"feed the cat\"}, \"extras\": {\"when\": \"today\", \"type\": \"task\"}}\n)\n\n# create a couple of tasks that can wait\nflake_create(\n    {\"user\": \"john\"},\n    {\"data\": {\"task\": \"buy food\"}, \"extras\": {\"when\": \"tomorrow\", \"type\": \"task\"}}\n)\nflake_create(\n    {\"user\": \"john\"},\n    {\"data\": {\"task\": \"update documentation\"}, \"extras\": {\"when\": \"tomorrow\", \"type\": \"task\"}}\n)\n\n# list all the tasks\nflake_list(\n    {\"user\": \"john\"},\n    {\"extras\": {\"type\": \"task\"}}\n)\n\n# list all the urgent tasks\nflake_list(\n    {\"user\": \"john\"},\n    {\"extras\": {\"type\": \"task\", \"when\": \"today\"}}\n)\n\n# list all the tasks for tomorrow\nflake_list(\n    {\"user\": \"john\"},\n    {\"extras\": {\"type\": \"task\", \"when\": \"tomorrow\"}}\n)\n```\n\n### Save the value of the option individually for every user\n\nScenario: each user can set a theme of application and this theme will be applied only for the current user\n\nFlakes are created for the user from the `context`. Flakes of the user A are\nvisible only to the user A, flakes of the user B exist in the different\nnamespace and are visible only to the user B.\n\nEach flake **can** have a name. Name must be unique among the flakes of the\nuser. But different users can use the same names for their flakes, because\nevery user has its own namespace for flakes.\n\nFlakes can be created either via `flakes_flake_create` action(accepts\n**optional** name and raises exception if name is not unique) or\n`flakes_flake_override`(requires a name and creates a new flake if name is not\ntaken or updates existing flake if name already used by some flake)\n\nIn order to get the flake use `flakes_flake_show` with the `id` of the flake or\n`flakes_flake_lookup` with the `name`.\n\n```python\n# set a theme for John\ntk.get_action(\"flakes_flake_override\")(\n    {\"user\": \"john\"},\n    {\"name\": \"application:theme\", \"data\": {\"theme\": \"dark\"}}\n)\n\n# set a theme for Mary\ntk.get_action(\"flakes_flake_override\")(\n    {\"user\": \"mary\"},\n    {\"name\": \"application:theme\", \"data\": {\"theme\": \"light\"}}\n)\n\n\n# get the value from the flake\njohn_theme = tk.get_action(\"flakes_flake_lookup\")(\n    {\"user\": \"john\"},\n    {\"name\": \"application:theme\"}\n)[\"data\"][\"theme\"]\n\nmary_theme = tk.get_action(\"flakes_flake_lookup\")(\n    {\"user\": \"mary\"},\n    {\"name\": \"application:theme\"}\n)[\"data\"][\"theme\"]\n\nassert john_theme == \"dark\"\nassert mary_theme == \"light\"\n```\n\n### Create and obtain global variable\n\nScenario: application requires global option, that can be changed in runtime\n\nBy default flakes are created in the \"namespace\" of the current user. Only the\nauthor can see and modify his own flakes.\n\nGlobal values should not be owned by someone, so here we need \"unowned\" flake -\nthe flake that is not connected to the particular user. Only sysadmin can\ncreate such flakes, so we are going to use `ignore_auth=True` attribute of the\ncontext.\n\nWe'll use `flakes_flake_override` action, that accepts a `name` of the flake\nand either updates existing flakes with this name or creates a new one if this\nname is free. In this way we'll avoid duplicates of the global flake.\n\n\n```python\n# create a flake\ntk.get_action(\"flakes_flake_override\")(\n    {\"ignore_auth\": True}, # only syadmin allowed to create unowned flakes with empty author id\n    {\"name\": \"global:config:value\", \"data\": {\"value\": 1}, \"author_id\": None}\n)\n\n# get the value from the flake\nvalue = tk.get_action(\"flakes_flake_lookup\")(\n    {\"ignore_auth\": True},\n    {\"name\": \"global:config:value\", \"author_id\": None}\n)[\"data\"][\"value\"]\n```\n\n\n## Example plugins\n\nThese plugins implement basic features that can be used as a real-life example\nof `ckanext-flakes` usage.\n\n### `flakes_rating`\n\nUser can rate a package via API action. Add\n`ckanext.flakes_rating.show_package_widget = true` to the config and default\nwidget will be added to the sidebar on `dataset.read` page.\n\n### `flakes_feedback`\n\nUser can leave a feedback for package via API action. Add\n`ckanext.flakes_feedback.enable_views = true` to the config and default page\nwill be added to navigation tabs on `dataset.read` page.\n\n## Requirements\n\nRequires python v3.7 or greater. Python v2 support doesn't require much effort,\nbut it neither worth the time you'll spend on it.\n\n\nCompatibility with core CKAN versions:\n\n| CKAN version | Compatible? |\n|--------------|-------------|\n| 2.9          | yes         |\n| 2.10         | yes         |\n\n\n## Installation\n\nTo install ckanext-flakes:\n\n1. Install it via **pip**:\n   ```sh\n   pip install ckanext-flakes\n   ```\n1. Add `flakes` to the `ckan.plugins` setting in your CKAN config file.\n1. Run DB migrations:\n   ```sh\n   ckan db upgrade -p flakes\n   ```\n\n## Configuration\n\n```ini\n# Any user can create a new flake.\n# (optional, default: true)\nckanext.flakes.creation.allowed = false\n\n# Any user can validate flake or plain data.\n# (optional, default: false)\nckanext.flakes.validation.allowed = true\n```\n\n## Interfaces\n\nProvides `ckanext.flakes.interfaces.IFlakes` interface. Always use\n`inherit=True` when implementing it, because it may change in the future.\n\nCurrently it provides the following hooks:\n\n```python\nclass IFlakes(Interface):\n    \"\"\"Extend functionality of ckanext-flakes\"\"\"\n\n    def get_flake_schemas(self) -> dict[str, dict[str, Any]]:\n        \"\"\"Register named validation schemas.\n\n        Used by `flakes_flake_validate` and `flakes_data_validate` actions.\n\n        Returns:\n            Mapping of names and corresponding validation schemas.\n\n        Example:\n            def get_flake_schemas(self) -> dict[str, dict[str, Any]]:\n                return {\n                    \"schema-that-requires-name\": {\"name\": [not_missing]}\n                }\n        \"\"\"\n        return {}\n\n    def get_flake_factories(self) -> dict[str, Callable[[dict[str, Any]], dict[str, Any]]]:\n        \"\"\"Register named example factories.\n\n        Used by `flakes_data_example` action.\n\n        Returns:\n            Mapping of names and corresponding example factories.\n\n        Example:\n            def get_flake_factories(self) -> dict[str, dict[str, Any]]:\n                def factory(payload: dict[str, Any]):\n                    return {\"field\": \"value\"}\n\n                return {\n                    \"test-factory\": factory\n                }\n        \"\"\"\n        return {}\n```\n\n\n## API\n\n### `flakes_flake_create`\n\nCreate a flake.\n\nArgs:\n\n    name (str, optional): name of the flake\n    data (dict): flake's data\n    parent_id (str, optional): ID of flake to extend\n    author_id (str, optional): author ID(can be set only by sysadmin)\n    extras (dict): flake's extra details\n\n### `flakes_flake_show`\n\nDisplay existing flake\n\nArgs:\n\n    id (str): ID of flake to display\n    expand (bool, optional): Extend flake using data from the parent flakes\n\n\n### `flakes_flake_list`\n\nDisplay all flakes of the user.\n\nIf `extras` dictionary passed, show only flakes that contains given extras. Example:\n\n    first_flake = Flake(extras={\"xxx\": {\"yyy\": \"hello\"}})\n    second_flake = Flake(extras={\"xxx\": {\"yyy\": \"world\"}})\n\n    flake_list(context, {\"extras\": {\"xxx\": {\"yyy\": \"hello\"}})\n    >>> first_flake\n\nArgs:\n\n    expand (bool, optional): Extend flake using data from the parent flakes\n    extras (dict, optional): Show only flakes whose extras contains passed dict\n    author_id (str, optional): author ID(can be set only by sysadmin)\n\n### `flakes_flake_update`\n\nUpdate existing flake\n\nArgs:\n\n    id (str): ID of flake to update\n    data (dict): flake's data\n    parent_id (str, optional): ID of flake to extend\n    extras (dict): flake's extra details\n\n### `flakes_flake_override`\n\nUpdate existing flake by name or create a new one.\n\nArgs:\n\n    name (str): Name flake to override\n    data (dict): template itself\n    parent_id (str, optional): ID of flake to extend\n    author_id (str, optional): author ID(can be set only by sysadmin if flake does not exist)\n    extras (dict): flake's extra details\n\n### `flakes_flake_delete`\n\nDelete existing flake\n\nArgs:\n\n    id (str): ID of flake to delete\n\n### `flakes_flake_lookup`\n\nDisplay flake using its name.\n\nArgs:\n\n    name (str): Name of the flake\n    expand (bool, optional): Extend flake using data from the parent flakes\n    author_id (str, optional): author ID(can be set only by sysadmin)\n\n### `flakes_flake_validate`\n\nValidate existing flake\n\nSchemas must be registered via `IFlakes` interface.\n\nArgs:\n\n    id (str): ID of flake to validate\n    expand (bool, optional): Extend flake using data from the parent flakes\n    schema(str): validation schema for the flake's data\n\n\n### `flakes_data_validate`\n\nValidate arbitrary data against the named schema(registered via IFlakes).\n\nArgs:\n\n    data (dict): data that needs to be validated\n    schema(str): validation schema for the data\n\n### `flakes_data_example`\n\nGenerate an example of the flake's data using named factory(registered via IFlakes).\n\nFactories must be registered via `IFlakes` interface.\n\nArgs:\n\n    factory(str): example factory\n    data (dict, optional): payload for the example factory\n\n### `flakes_flake_materialize`\n\nSend flake's data to API action.\n\nArgs:\n\n    id (str): ID of flake to materialize\n    expand (bool, optional): Extend flake using data from the parent flakes\n    remove (bool, optional): Remove flake after materialization\n    action (str): API action to use for materialization\n\n### `flakes_flake_combine`\n\nCombine data from multiple flakes\n\n`id` argument specifies all the flakes that must be combined. All of the flakes\nmust exist, otherwise `NotFound` error raised. IDs at the start of the list have\nhigher priority(override matching keys). IDs at the end of the list have lower\npriority(can be shadowed by former flakes).\n\n`expand` must be a `dict[str, bool]`. Keys are IDs of the flakes, values are\nexpand flags for the corresponding flake.\n\nArgs:\n\n    id (list): IDs of flakes.\n    expand (dict, optional): Extend flake using data from the parent flakes\n\n### `flakes_flake_merge`\n\nCombine multiple flakes and save the result.\n\nArgs:\n\n    id (list): IDs of flakes.\n    expand (dict, optional): Extend flake using data from the parent flakes\n    remove (bool, optional): Remove flakes after the operation.\n    destination (str, optional): Save data into the specified flake instead of a new one\n\n### `flakes_data_patch`\n\nPartially overrides data leaving other fields intact.\n\nArgs:\n\n    id (str): ID of flake\n    data (dict): patch for data\n\n\n### `flakes_extras_patch`\n\nPartially overrides extras leaving other fields intact.\n\nArgs:\n\n    id (str): ID of flake\n    extras (dict): patch for extras\n\n## Developer installation\n\nTo install ckanext-flakes for development, activate your CKAN virtualenv and\ndo:\n\n    git clone https://github.com/DataShades/ckanext-flakes.git\n    cd ckanext-flakes\n    python setup.py develop\n\n\n## Tests\n\nTo run the tests, do:\n\n    pytest\n\n## License\n\n[AGPL](https://www.gnu.org/licenses/agpl-3.0.en.html)\n",
    "bugtrack_url": null,
    "license": "AGPL",
    "summary": "",
    "version": "0.4.5",
    "project_urls": {
        "Homepage": "https://github.com/DataShades/ckanext-flakes"
    },
    "split_keywords": [
        "ckan"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a9d0b8ab0dce57662bd36488e3ec5694130dfd9043407af9def67103b57c50b1",
                "md5": "067f1b729f87f05189a8711e1da27393",
                "sha256": "d979b42bdc86b350ac26c72fc0f5d74439ea49496a4b140dc826a0e9ae05b330"
            },
            "downloads": -1,
            "filename": "ckanext_flakes-0.4.5-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "067f1b729f87f05189a8711e1da27393",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 57058,
            "upload_time": "2023-07-03T12:11:02",
            "upload_time_iso_8601": "2023-07-03T12:11:02.771902Z",
            "url": "https://files.pythonhosted.org/packages/a9/d0/b8ab0dce57662bd36488e3ec5694130dfd9043407af9def67103b57c50b1/ckanext_flakes-0.4.5-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "328285ecc5e218d5ff4897b2268bec6bde8ba8bc2ad535d10291a2b4a413a1dd",
                "md5": "eb2621c24c3a23af3df4a0331c889afc",
                "sha256": "8aae3ac69298c8aae85402a44354a02a84cecb37c2eb7c84bcd8d331abe5a98f"
            },
            "downloads": -1,
            "filename": "ckanext-flakes-0.4.5.tar.gz",
            "has_sig": false,
            "md5_digest": "eb2621c24c3a23af3df4a0331c889afc",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 45950,
            "upload_time": "2023-07-03T12:11:04",
            "upload_time_iso_8601": "2023-07-03T12:11:04.926143Z",
            "url": "https://files.pythonhosted.org/packages/32/82/85ecc5e218d5ff4897b2268bec6bde8ba8bc2ad535d10291a2b4a413a1dd/ckanext-flakes-0.4.5.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-07-03 12:11:04",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "DataShades",
    "github_project": "ckanext-flakes",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "ckanext-flakes"
}
        
Elapsed time: 0.08187s