alchemyjsonschema
=================
.. |Python package| image:: https://github.com/podhmo/alchemyjsonschema/actions/workflows/python-package.yml/badge.svg
:target: https://github.com/podhmo/alchemyjsonschema/actions/workflows/python-package.yml
features
----------------------------------------
alchemyjsonschema is the library for converting sqlalchemys's model to jsonschema.
- using alchemyjsonschema as command
- using alchemyjsonschema as library
as library
----------------------------------------
having three output styles.
- NoForeignKeyWalker -- ignore relationships
- ForeignKeyWalker -- expecting the information about relationship is foreign key
- StructuralWalker -- fullset output(expecting the information about relationship is full JSON data)
examples
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
dumping json with above three output styles.
target models are here. Group and User.
.. code:: python
# -*- coding:utf-8 -*-
import sqlalchemy as sa
import sqlalchemy.orm as orm
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Group(Base):
"""model for test"""
__tablename__ = "Group"
pk = sa.Column(sa.Integer, primary_key=True, doc="primary key")
name = sa.Column(sa.String(255), default="", nullable=False)
class User(Base):
__tablename__ = "User"
pk = sa.Column(sa.Integer, primary_key=True, doc="primary key")
name = sa.Column(sa.String(255), default="", nullable=True)
group_id = sa.Column(sa.Integer, sa.ForeignKey(Group.pk), nullable=False)
group = orm.relationship(Group, uselist=False, backref="users")
NoForeignKeyWalker
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: python
import pprint as pp
from alchemyjsonschema import SchemaFactory
from alchemyjsonschema import NoForeignKeyWalker
factory = SchemaFactory(NoForeignKeyWalker)
pp.pprint(factory(User))
"""
{'properties': {'name': {'maxLength': 255, 'type': 'string'},
'pk': {'description': 'primary key', 'type': 'integer'}},
'required': ['pk'],
'title': 'User',
'type': 'object'}
"""
ForeignKeyWalker
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: python
import pprint as pp
from alchemyjsonschema import SchemaFactory
from alchemyjsonschema import ForeignKeyWalker
factory = SchemaFactory(ForeignKeyWalker)
pp.pprint(factory(User))
"""
{'properties': {'group_id': {'type': 'integer'},
'name': {'maxLength': 255, 'type': 'string'},
'pk': {'description': 'primary key', 'type': 'integer'}},
'required': ['pk', 'group_id'],
'title': 'User',
'type': 'object'}
"""
StructuralWalker
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. code:: python
import pprint as pp
from alchemyjsonschema import SchemaFactory
from alchemyjsonschema import StructuralWalker
factory = SchemaFactory(StructuralWalker)
pp.pprint(factory(User))
"""
{'definitions': {'Group': {'properties': {'pk': {'description': 'primary key',
'type': 'integer'},
'name': {'maxLength': 255,
'type': 'string'}},
'type': 'object'}},
'properties': {'pk': {'description': 'primary key', 'type': 'integer'},
'name': {'maxLength': 255, 'type': 'string'},
'group': {'$ref': '#/definitions/Group'}},
'required': ['pk'],
'title': 'User',
'type': 'object'}
"""
pp.pprint(factory(Group))
"""
{'definitions': {'User': {'properties': {'pk': {'description': 'primary key',
'type': 'integer'},
'name': {'maxLength': 255,
'type': 'string'}},
'type': 'object'}},
'description': 'model for test',
'properties': {'pk': {'description': 'primary key', 'type': 'integer'},
'name': {'maxLength': 255, 'type': 'string'},
'users': {'items': {'$ref': '#/definitions/User'},
'type': 'array'}},
'required': ['pk', 'name'],
'title': 'Group',
'type': 'object'}
"""
as command
----------------------------------------
using alchemyjsonschema as command (the command name is also `alchemyjsonschema`).
help
.. code:: bash
$ alchemyjsonschema --help
usage: alchemyjsonschema [-h] [--walker {noforeignkey,foreignkey,structural}]
[--decision {default,fullset}] [--depth DEPTH]
[--out OUT]
target
positional arguments:
target the module or class to extract schemas from
optional arguments:
-h, --help show this help message and exit
--walker {noforeignkey,foreignkey,structural}
--decision {default,fullset}
--depth DEPTH
--out OUT output to file
If above two model definitions (User,Group) are existed in `alchemyjsonschema.tests.models` .
Target is the class position or module position. for example,
- class position -- `alchemyjsonschema.tests.models:User`
- module position -- `alchemyjsonschema.tests.models`
example
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Using StructuralWalker via command line (--walker structural).
Of course, NoForeignKeyWalker is noforeignkey, and ForeignKeyWalker is foreignkey.
.. code:: bash
$ alchemyjsonschema --walker structural alchemyjsonschema.tests.models:Group
{
"definitions": {
"Group": {
"properties": {
"color": {
"enum": [
"red",
"green",
"yellow",
"blue"
],
"maxLength": 6,
"type": "string"
},
"created_at": {
"format": "date-time",
"type": "string"
},
"name": {
"maxLength": 255,
"type": "string"
},
"pk": {
"description": "primary key",
"type": "integer"
},
"users": {
"items": {
"$ref": "#/definitions/User"
},
"type": "array"
}
},
"required": [
"pk"
],
"title": "Group",
"type": "object"
},
"User": {
"properties": {
"created_at": {
"format": "date-time",
"type": "string"
},
"name": {
"maxLength": 255,
"type": "string"
},
"pk": {
"description": "primary key",
"type": "integer"
}
},
"required": [
"pk"
],
"type": "object"
}
}
}
Output is not same when using Walker-class, directly. This is handy output for something like a swagger(OpenAPI 2.0)'s tool.
appendix: what is `--decision` ?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
what is `--decision`? (TODO: gentle description)
.. code-block:: bash
$ alchemyjsonschema --walker structural alchemyjsonschema.tests.models:User | jq . -S > /tmp/default.json
$ alchemyjsonschema --decision useforeignkey --walker structural alchemyjsonschema.tests.models:User | jq . -S > /tmp/useforeignkey.json
$ diff -u /tmp/default.json /tmp/useforeignkey.json
.. code-block:: diff
--- /tmp/default.json 2017-01-02 22:49:44.000000000 +0900
+++ /tmp/useforeignkey.json 2017-01-02 22:53:13.000000000 +0900
@@ -1,43 +1,14 @@
{
"definitions": {
- "Group": {
- "properties": {
- "color": {
- "enum": [
- "red",
- "green",
- "yellow",
- "blue"
- ],
- "maxLength": 6,
- "type": "string"
- },
- "created_at": {
- "format": "date-time",
- "type": "string"
- },
- "name": {
- "maxLength": 255,
- "type": "string"
- },
- "pk": {
- "description": "primary key",
- "type": "integer"
- }
- },
- "required": [
- "pk"
- ],
- "type": "object"
- },
"User": {
"properties": {
"created_at": {
"format": "date-time",
"type": "string"
},
- "group": {
- "$ref": "#/definitions/Group"
+ "group_id": {
+ "relation": "group",
+ "type": "integer"
},
"name": {
"maxLength": 255,
1.0.0
- added types for JSON fields
0.7.1
- adjust_required() option
0.7.0
- see server_default
- omit python 2.x
0.6.1
- catch up magicalimport 0.8.1
0.6.0
- fix for jsonschema-update
0.4.2
- fix bug calling command with module (not model class)
0.4.0
- remove needless feature(#11)
0.3
- swagger support(thanks of isysd)
Raw data
{
"_id": null,
"home_page": "https://github.com/splautz/alchemyjsonschema.git",
"name": "mstax-alchemyjsonschema",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "alchemyjsonschema sqlalchemy jsonschema schema-generation",
"author": "splautz",
"author_email": "",
"download_url": "https://files.pythonhosted.org/packages/5c/00/60cc99123c0dbacbc3fa66b36d3f5ead234883f02f954704d631557cb155/mstax-alchemyjsonschema-1.0.0.tar.gz",
"platform": null,
"description": "alchemyjsonschema\n=================\n\n.. |Python package| image:: https://github.com/podhmo/alchemyjsonschema/actions/workflows/python-package.yml/badge.svg\n :target: https://github.com/podhmo/alchemyjsonschema/actions/workflows/python-package.yml\n\nfeatures\n----------------------------------------\n\nalchemyjsonschema is the library for converting sqlalchemys's model to jsonschema.\n\n- using alchemyjsonschema as command\n- using alchemyjsonschema as library\n\nas library\n----------------------------------------\n\nhaving three output styles.\n\n- NoForeignKeyWalker -- ignore relationships\n- ForeignKeyWalker -- expecting the information about relationship is foreign key\n- StructuralWalker -- fullset output(expecting the information about relationship is full JSON data)\n\nexamples\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\ndumping json with above three output styles.\n\ntarget models are here. Group and User.\n\n.. code:: python\n\n # -*- coding:utf-8 -*-\n import sqlalchemy as sa\n import sqlalchemy.orm as orm\n from sqlalchemy.ext.declarative import declarative_base\n\n Base = declarative_base()\n\n\n class Group(Base):\n \"\"\"model for test\"\"\"\n __tablename__ = \"Group\"\n\n pk = sa.Column(sa.Integer, primary_key=True, doc=\"primary key\")\n name = sa.Column(sa.String(255), default=\"\", nullable=False)\n\n\n class User(Base):\n __tablename__ = \"User\"\n\n pk = sa.Column(sa.Integer, primary_key=True, doc=\"primary key\")\n name = sa.Column(sa.String(255), default=\"\", nullable=True)\n group_id = sa.Column(sa.Integer, sa.ForeignKey(Group.pk), nullable=False)\n group = orm.relationship(Group, uselist=False, backref=\"users\")\n\n\nNoForeignKeyWalker\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n import pprint as pp\n from alchemyjsonschema import SchemaFactory\n from alchemyjsonschema import NoForeignKeyWalker\n\n factory = SchemaFactory(NoForeignKeyWalker)\n pp.pprint(factory(User))\n\n \"\"\"\n {'properties': {'name': {'maxLength': 255, 'type': 'string'},\n 'pk': {'description': 'primary key', 'type': 'integer'}},\n 'required': ['pk'],\n 'title': 'User',\n 'type': 'object'}\n \"\"\"\n\n\nForeignKeyWalker\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. code:: python\n\n import pprint as pp\n from alchemyjsonschema import SchemaFactory\n from alchemyjsonschema import ForeignKeyWalker\n\n factory = SchemaFactory(ForeignKeyWalker)\n pp.pprint(factory(User))\n\n \"\"\"\n {'properties': {'group_id': {'type': 'integer'},\n 'name': {'maxLength': 255, 'type': 'string'},\n 'pk': {'description': 'primary key', 'type': 'integer'}},\n 'required': ['pk', 'group_id'],\n 'title': 'User',\n 'type': 'object'}\n \"\"\"\n\n\nStructuralWalker\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n\n.. code:: python\n\n import pprint as pp\n from alchemyjsonschema import SchemaFactory\n from alchemyjsonschema import StructuralWalker\n\n factory = SchemaFactory(StructuralWalker)\n pp.pprint(factory(User))\n\n \"\"\"\n {'definitions': {'Group': {'properties': {'pk': {'description': 'primary key',\n 'type': 'integer'},\n 'name': {'maxLength': 255,\n 'type': 'string'}},\n 'type': 'object'}},\n 'properties': {'pk': {'description': 'primary key', 'type': 'integer'},\n 'name': {'maxLength': 255, 'type': 'string'},\n 'group': {'$ref': '#/definitions/Group'}},\n 'required': ['pk'],\n 'title': 'User',\n 'type': 'object'}\n \"\"\"\n\n pp.pprint(factory(Group))\n\n \"\"\"\n {'definitions': {'User': {'properties': {'pk': {'description': 'primary key',\n 'type': 'integer'},\n 'name': {'maxLength': 255,\n 'type': 'string'}},\n 'type': 'object'}},\n 'description': 'model for test',\n 'properties': {'pk': {'description': 'primary key', 'type': 'integer'},\n 'name': {'maxLength': 255, 'type': 'string'},\n 'users': {'items': {'$ref': '#/definitions/User'},\n 'type': 'array'}},\n 'required': ['pk', 'name'],\n 'title': 'Group',\n 'type': 'object'}\n \"\"\"\n\nas command\n----------------------------------------\n\nusing alchemyjsonschema as command (the command name is also `alchemyjsonschema`).\n\nhelp\n\n.. code:: bash\n\n $ alchemyjsonschema --help\n usage: alchemyjsonschema [-h] [--walker {noforeignkey,foreignkey,structural}]\n [--decision {default,fullset}] [--depth DEPTH]\n [--out OUT]\n target\n\n positional arguments:\n target the module or class to extract schemas from\n\n optional arguments:\n -h, --help show this help message and exit\n --walker {noforeignkey,foreignkey,structural}\n --decision {default,fullset}\n --depth DEPTH\n --out OUT output to file\n\nIf above two model definitions (User,Group) are existed in `alchemyjsonschema.tests.models` .\n\nTarget is the class position or module position. for example,\n\n- class position -- `alchemyjsonschema.tests.models:User`\n- module position -- `alchemyjsonschema.tests.models`\n\nexample\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nUsing StructuralWalker via command line (--walker structural).\nOf course, NoForeignKeyWalker is noforeignkey, and ForeignKeyWalker is foreignkey.\n\n.. code:: bash\n\n $ alchemyjsonschema --walker structural alchemyjsonschema.tests.models:Group\n\n {\n \"definitions\": {\n \"Group\": {\n \"properties\": {\n \"color\": {\n \"enum\": [\n \"red\",\n \"green\",\n \"yellow\",\n \"blue\"\n ],\n \"maxLength\": 6,\n \"type\": \"string\"\n },\n \"created_at\": {\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"name\": {\n \"maxLength\": 255,\n \"type\": \"string\"\n },\n \"pk\": {\n \"description\": \"primary key\",\n \"type\": \"integer\"\n },\n \"users\": {\n \"items\": {\n \"$ref\": \"#/definitions/User\"\n },\n \"type\": \"array\"\n }\n },\n \"required\": [\n \"pk\"\n ],\n \"title\": \"Group\",\n \"type\": \"object\"\n },\n \"User\": {\n \"properties\": {\n \"created_at\": {\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n \"name\": {\n \"maxLength\": 255,\n \"type\": \"string\"\n },\n \"pk\": {\n \"description\": \"primary key\",\n \"type\": \"integer\"\n }\n },\n \"required\": [\n \"pk\"\n ],\n \"type\": \"object\"\n }\n }\n }\n\nOutput is not same when using Walker-class, directly. This is handy output for something like a swagger(OpenAPI 2.0)'s tool.\n\nappendix: what is `--decision` ?\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nwhat is `--decision`? (TODO: gentle description)\n\n.. code-block:: bash\n\n $ alchemyjsonschema --walker structural alchemyjsonschema.tests.models:User | jq . -S > /tmp/default.json\n $ alchemyjsonschema --decision useforeignkey --walker structural alchemyjsonschema.tests.models:User | jq . -S > /tmp/useforeignkey.json\n $ diff -u /tmp/default.json /tmp/useforeignkey.json\n\n.. code-block:: diff\n\n --- /tmp/default.json\t2017-01-02 22:49:44.000000000 +0900\n +++ /tmp/useforeignkey.json\t2017-01-02 22:53:13.000000000 +0900\n @@ -1,43 +1,14 @@\n {\n \"definitions\": {\n - \"Group\": {\n - \"properties\": {\n - \"color\": {\n - \"enum\": [\n - \"red\",\n - \"green\",\n - \"yellow\",\n - \"blue\"\n - ],\n - \"maxLength\": 6,\n - \"type\": \"string\"\n - },\n - \"created_at\": {\n - \"format\": \"date-time\",\n - \"type\": \"string\"\n - },\n - \"name\": {\n - \"maxLength\": 255,\n - \"type\": \"string\"\n - },\n - \"pk\": {\n - \"description\": \"primary key\",\n - \"type\": \"integer\"\n - }\n - },\n - \"required\": [\n - \"pk\"\n - ],\n - \"type\": \"object\"\n - },\n \"User\": {\n \"properties\": {\n \"created_at\": {\n \"format\": \"date-time\",\n \"type\": \"string\"\n },\n - \"group\": {\n - \"$ref\": \"#/definitions/Group\"\n + \"group_id\": {\n + \"relation\": \"group\",\n + \"type\": \"integer\"\n },\n \"name\": {\n \"maxLength\": 255,\n\n\n1.0.0\n\n- added types for JSON fields\n\n0.7.1\n\n- adjust_required() option\n\n0.7.0\n\n- see server_default\n- omit python 2.x\n\n0.6.1\n\n- catch up magicalimport 0.8.1\n\n0.6.0\n\n- fix for jsonschema-update\n\n0.4.2\n\n- fix bug calling command with module (not model class)\n\n0.4.0\n\n- remove needless feature(#11)\n\n0.3\n\n- swagger support(thanks of isysd)\n",
"bugtrack_url": null,
"license": "mit",
"summary": "A package for generating json-schema models from sqlalchemy models.",
"version": "1.0.0",
"split_keywords": [
"alchemyjsonschema",
"sqlalchemy",
"jsonschema",
"schema-generation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "7497cb3ebc01b441086dbb60bc779799c3f6473488d6509abff9cafd435122f0",
"md5": "c86dda766088e37d9fec5d0572b305c3",
"sha256": "a3cb5e5fd3bf1389eb4a9654102fd870c548fef331ec32a402f1162caf1bb678"
},
"downloads": -1,
"filename": "mstax_alchemyjsonschema-1.0.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "c86dda766088e37d9fec5d0572b305c3",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": null,
"size": 17605,
"upload_time": "2023-03-27T15:30:25",
"upload_time_iso_8601": "2023-03-27T15:30:25.366471Z",
"url": "https://files.pythonhosted.org/packages/74/97/cb3ebc01b441086dbb60bc779799c3f6473488d6509abff9cafd435122f0/mstax_alchemyjsonschema-1.0.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5c0060cc99123c0dbacbc3fa66b36d3f5ead234883f02f954704d631557cb155",
"md5": "21321a5c99346b68c51b5a39e9445fc4",
"sha256": "37069b211b0cf0102570e7855baaf56d0a40113a42e38b95693f4cb44b77dd39"
},
"downloads": -1,
"filename": "mstax-alchemyjsonschema-1.0.0.tar.gz",
"has_sig": false,
"md5_digest": "21321a5c99346b68c51b5a39e9445fc4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 16994,
"upload_time": "2023-03-27T15:30:27",
"upload_time_iso_8601": "2023-03-27T15:30:27.966272Z",
"url": "https://files.pythonhosted.org/packages/5c/00/60cc99123c0dbacbc3fa66b36d3f5ead234883f02f954704d631557cb155/mstax-alchemyjsonschema-1.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-27 15:30:27",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "splautz",
"github_project": "alchemyjsonschema.git",
"lcname": "mstax-alchemyjsonschema"
}