Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .github/actions/test/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Test'

inputs:
python-version:
description: 'Python version to test with'
required: true
type: string
pytest-args:
description: 'pytest args to test with'
required: false
default: ''
type: string

runs:
using: "composite"
steps:
- name: Set up Python ${{ inputs.python-version }}
uses: actions/setup-python@v2
with:
python-version: ${{ inputs.python-version }}
- name: Install dependencies
shell: bash
run: |
python -m pip install --upgrade pip build
python -m build
python -m pip install '.[test]'
python -m pip install wheel pytest pytest-cov pytest-xdist requests "coveralls<4" codacy-coverage
pip install --ignore-installed pytest>=4.4.0
pytest --version
- name: Test with pytest
shell: bash
run: |
pytest ${{ inputs.pytest-args }} -m "not no_expected" -n 8 test/
40 changes: 16 additions & 24 deletions .github/workflows/test_and_release.yml
Original file line number Diff line number Diff line change
@@ -1,38 +1,30 @@
name: Build 📦

on: [ push, pull_request ]
on:
- push
- pull_request

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11' ]
python-version: [ '3.9', '3.10', '3.11', '3.12' ]

steps:
- uses: actions/checkout@v2
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
- name: Test
uses: ./.github/actions/test
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python setup.py sdist
python setup.py install
python -m pip install wheel pytest pytest-cov pytest-xdist requests coveralls codacy-coverage
pip install --ignore-installed pytest>=4.4.0
pytest --version
- name: Test with pytest
run: |
python setup.py test -a '--cov-config .coveragerc --cov=json_to_models -m "not no_expected" test/'
- name: Coverage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
coverage xml
coveralls --service=github
pytest-args: '--cov-config .coveragerc --cov=json_to_models'
# - name: Coverage
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# run: |
# coverage xml
# coveralls --service=github
# TODO: Fix codacy issue with token
# python-codacy-coverage -r coverage.xml

Expand All @@ -43,17 +35,17 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.7
- name: Set up Python 3.11
uses: actions/setup-python@v2
with:
python-version: 3.7
python-version: 3.11
- name: Install deps
run: |
python -m pip install --upgrade pip
pip install setuptools wheel twine
- name: Build a binary wheel and a source tarball
run: |
python setup.py sdist bdist_wheel
python -m build
- name: Publish distribution 📦 to PyPI
env:
TWINE_USERNAME: __token__
Expand Down
21 changes: 21 additions & 0 deletions .github/workflows/test_every_week.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Test every month

on:
schedule:
- cron: "0 * * * *"
# - cron: "0 0 1 * *"

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: [ '3.9', '3.10', '3.11', '3.12' ]

steps:
- uses: actions/checkout@v2
- name: Test
uses: ./.github/actions/test
with:
python-version: ${{ matrix.python-version }}
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -444,9 +444,6 @@ class Swagger(BaseModel):

## Installation

| **Beware**: this project supports only `python3.7` and higher. |
| --- |

To install it, use `pip`:

`pip install json2python-models`
Expand Down
5 changes: 1 addition & 4 deletions json_to_models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
from pkg_resources import parse_version

__version__ = "0.3.0"
VERSION = parse_version(__version__)
__version__ = "0.3.1"
9 changes: 6 additions & 3 deletions json_to_models/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@

try:
import ruamel.yaml as yaml

yaml_load = yaml.YAML(typ='safe', pure=True).load
except ImportError:
try:
import yaml
yaml_load = yaml.safe_load
except ImportError:
yaml = None

Expand Down Expand Up @@ -417,11 +420,11 @@ def json(path: Path) -> Union[dict, list]:

@staticmethod
def yaml(path: Path) -> Union[dict, list]:
if yaml is None:
print('Yaml parser is not installed. To parse yaml files PyYaml (or ruamel.yaml) is required.')
if yaml_load is None:
print('Yaml parser is not installed. To parse yaml files ruamel.yaml (or PyYaml) is required.')
raise ImportError('yaml')
with path.open() as fp:
return yaml.safe_load(fp)
return yaml_load(fp)

@staticmethod
def ini(path: Path) -> dict:
Expand Down
2 changes: 1 addition & 1 deletion json_to_models/models/pydantic.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def generate(self, nested_classes: List[str] = None, extra: str = "", **kwargs)
nested_classes=nested_classes,
extra=extra
)
imports.append(('pydantic', ['BaseModel', 'Field']))
imports.append(('pydantic.v1', ['BaseModel', 'Field']))
return imports, body

def _filter_fields(self, fields):
Expand Down
50 changes: 50 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[build-system]
requires = ["setuptools"]
build-backend = "setuptools.build_meta"

[project]
name = "json2python-models"
description = "Python models (pydantic, attrs, dataclasses or custom) generator from JSON data with typing module support"
readme = "README.md"
license = { text = "MIT" }
requires-python = ">=3.9"
authors = [
{ name = "bogdandm (Bogdan Kalashnikov)", email = "[email protected]" }
]
dynamic = ['version', 'dependencies']

[project.urls]
"Repository" = "https://github.com/bogdandm/json2python-models"

[project.optional-dependencies]
test = [
"pytest>=4.4.0",
"pytest-xdist",
"pytest-cov",
"requests",
"attrs",
"pydantic>=1.3",
"ruamel.yaml",
"coverage"
]

[project.scripts]
json2models = "json_to_models.cli:main"

[tool.setuptools]
packages = { find = { exclude = ["test", "testing_tools"] } }

[tool.setuptools.dynamic]
dependencies = { file = ["requirements.txt"] }
version = { attr = "json_to_models.__version__" }
readme = { file = ['README.md'] }

[tool.setuptools.package-data]
"*" = ['*.txt.', '*.ini', ".coveragerc", "LICENSE", "*.md"]

[tool.pytest.ini_options]
testpaths = ["tests"]
markers = [
"no_expected: testing data has no expected value",
"slow_http: api that provides testing data is slow"
]
4 changes: 0 additions & 4 deletions pytest.ini

This file was deleted.

10 changes: 5 additions & 5 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
python-dateutil>=2.7.*
inflection>=0.3.*
unidecode>=1.0.*
Jinja2>=2.10.*
python-dateutil>=2.7
inflection>=0.3
unidecode>=1.0
Jinja2>=2.10
ordered-set==4.*
typing-extensions>=3.1.*
typing-extensions>=3.1
File renamed without changes.
20 changes: 11 additions & 9 deletions test/test_cli/test_script.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import imp
import json
import re
import subprocess
import sys
import tempfile
import types
import uuid
from pathlib import Path
from time import time
from typing import Tuple

import pytest

Expand Down Expand Up @@ -95,6 +95,14 @@ def test_help():
]


def load_model(code, module_name=''):
module_name = module_name or uuid.uuid4().hex
module = types.ModuleType(module_name)
sys.modules[module_name] = module
exec(code, module.__dict__)
return module


def execute_test(command, output_file: Path = None, output=None) -> str:
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout, stderr = map(bytes.decode, proc.communicate())
Expand All @@ -107,13 +115,7 @@ def execute_test(command, output_file: Path = None, output=None) -> str:
assert not stderr, stderr
assert stdout, stdout
assert proc.returncode == 0
# Note: imp package is deprecated but I can't find a way to create dummy module using importlib
module = imp.new_module("test_model")
sys.modules["test_model"] = module
try:
exec(compile(stdout, "test_model.py", "exec"), module.__dict__)
except Exception as e:
assert not e, stdout
load_model(stdout)

print(stdout)
return stdout
Expand Down
17 changes: 5 additions & 12 deletions test/test_cli/test_self_validate_pydantic.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import imp
import json
import sys
from inspect import isclass

import pydantic
import pydantic.v1 as pydantic
import pytest

from json_to_models.generator import MetadataGenerator
from json_to_models.models.base import generate_code
from json_to_models.models.pydantic import PydanticModelCodeGenerator
from json_to_models.models.structure import compose_models_flat
from json_to_models.registry import ModelRegistry
from .test_script import test_data_path
from .test_script import test_data_path, load_model

test_self_validate_pydantic_data = [
pytest.param(test_data_path / "gists.json", list, id="gists.json"),
Expand Down Expand Up @@ -39,14 +37,9 @@ def test_self_validate_pydantic(data, data_type):

structure = compose_models_flat(reg.models_map)
code = generate_code(structure, PydanticModelCodeGenerator)
module = imp.new_module("test_models")
sys.modules["test_models"] = module
try:
exec(compile(code, "test_models.py", "exec"), module.__dict__)
except Exception as e:
assert not e, code

import test_models

test_models = load_model(code, 'test_models')

for name in dir(test_models):
cls = getattr(test_models, name)
if isclass(cls) and issubclass(cls, pydantic.BaseModel):
Expand Down
6 changes: 3 additions & 3 deletions test/test_code_generation/test_pydantic_generation.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
]
},
"generated": trim(f"""
from pydantic import BaseModel, Field
from pydantic.v1 import BaseModel, Field


class Test(BaseModel):
Expand Down Expand Up @@ -120,7 +120,7 @@ class Test(BaseModel):
}
},
"generated": trim(f"""
from pydantic import BaseModel, Field
from pydantic.v1 import BaseModel, Field
from typing import Dict, List, Optional


Expand All @@ -146,7 +146,7 @@ class Test(BaseModel):
"u": DUnion(DDict(IntString), DList(DList(IntString))),
}),
"generated": trim("""
from pydantic import BaseModel, Field
from pydantic.v1 import BaseModel, Field
from typing import Dict, List, Optional, Union


Expand Down
Loading