Skip to content
Open
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
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI

on:
pull_request:
branches: [master]
push:
branches: [master]

jobs:
test:
name: Test (Python ${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]

steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Set up Python ${{ matrix.python-version }}
run: uv python install ${{ matrix.python-version }}

- name: Install dependencies
run: uv sync --dev

- name: Run tests
run: uv run pytest tests/ -v --cov=restea --cov-report=term-missing

lint:
name: Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Set up Python
run: uv python install 3.12

- name: Check with ruff
run: uvx ruff check .
53 changes: 53 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Build and Publish

on:
push:
tags:
- '*'

permissions:
contents: write

jobs:
build:
name: Build distribution
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Needed for hatch-vcs to get version from tags

- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: "latest"

- name: Set up Python
run: uv python install 3.12

- name: Build package
run: uv build

- name: Store distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/

publish-to-github:
name: Publish to GitHub Release
needs: build
runs-on: ubuntu-latest

steps:
- name: Download distribution packages
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/

- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
files: dist/*
generate_release_notes: true
10 changes: 6 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
.coverage
htmlcov/*
MANIFEST
dist
dist/
.cache
.eggs/*
build/*
restea.egg-info/*
.eggs/
build/
*.egg-info/
.venv/
.python-version
6 changes: 3 additions & 3 deletions example.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import random

from flask import Flask

from restea import errors
from restea.resource import Resource
from restea import errors, fields
from restea.adapters.flaskwrap import FlaskResourceWrapper
from restea import fields
from restea.resource import Resource

app = Flask(__name__)

Expand Down
82 changes: 82 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
[build-system]
requires = ["hatchling", "uv-dynamic-versioning"]
build-backend = "hatchling.build"

[project]
name = "restea"
dynamic = ["version"]
description = "Simple RESTful server toolkit"
readme = "README.rst"
license = "MIT"
requires-python = ">=3.10"
authors = [
{ name = "Walery Jadlowski", email = "bodb.digr@gmail.com" },
]
keywords = ["rest", "restful", "restea"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Internet :: WWW/HTTP",
]
dependencies = []

[project.optional-dependencies]
dev = [
"pytest>=7.0",
"pytest-cov>=4.0",
"pytest-mock>=3.0",
"mock>=5.0",
]

[dependency-groups]
dev = [
"pytest>=7.0",
"pytest-cov>=4.0",
"pytest-mock>=3.0",
"mock>=5.0",
]

[project.urls]
Homepage = "https://github.com/bodbdigr/restea"
Repository = "https://github.com/bodbdigr/restea"

[tool.hatch.version]
source = "uv-dynamic-versioning"

[tool.uv-dynamic-versioning]
fallback-version = "0.0.0"

[tool.hatch.build.targets.sdist]
include = [
"/restea",
"/README.rst",
]

[tool.hatch.build.targets.wheel]
packages = ["restea"]

[tool.pytest.ini_options]
addopts = "--cov-report=term-missing --cov=restea"
testpaths = ["tests"]

[tool.ruff]
target-version = "py310"
line-length = 88

[tool.ruff.lint]
select = ["E", "F", "I"]
ignore = ["E501"]

[tool.ruff.lint.isort]
known-first-party = ["restea"]
7 changes: 6 additions & 1 deletion restea/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
__version__ = '0.3.10'
import importlib.metadata

try:
__version__ = importlib.metadata.version(__name__)
except importlib.metadata.PackageNotFoundError:
__version__ = "0.0.0"
6 changes: 2 additions & 4 deletions restea/adapters/djangowrap.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import six

from django.http import HttpResponse
from django.urls import re_path

from restea.adapters.base import (
BaseResourceWrapper,
BaseRequestWrapper,
BaseResourceWrapper,
)


Expand Down Expand Up @@ -63,7 +61,7 @@ def prepare_response(self, content, status_code, content_type, headers):
content_type=content_type,
status=status_code
)
for name, value in six.iteritems(headers):
for name, value in headers.items():
response[name] = value
return response

Expand Down
6 changes: 2 additions & 4 deletions restea/adapters/flaskwrap.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import six

import flask

from restea.adapters.base import (
BaseResourceWrapper,
BaseRequestWrapper,
BaseResourceWrapper,
)


Expand Down Expand Up @@ -73,7 +71,7 @@ def prepare_response(self, content, status_code, content_type, headers):
mimetype=content_type,
status=status_code
)
for name, value in six.iteritems(headers):
for name, value in headers.items():
response.headers[name] = value
return response

Expand Down
8 changes: 3 additions & 5 deletions restea/adapters/wheezywebwrap.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import six

from wheezy.http import HTTPResponse
from wheezy.routing import url
from wheezy.http.comp import bton
from wheezy.routing import url

from restea.adapters.base import (
BaseResourceWrapper,
BaseRequestWrapper,
BaseResourceWrapper,
)
from restea.errors import BadRequestError

Expand Down Expand Up @@ -76,7 +74,7 @@ def prepare_response(self, content, status_code, content_type, headers):
response = HTTPResponse(content_type=content_type)
response.write(content)
response.status_code = status_code
for name, value in six.iteritems(headers):
for name, value in headers.items():
response.headers.append((name, value))
return response

Expand Down
9 changes: 3 additions & 6 deletions restea/fields.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import re
import datetime

import six
from six.moves import map
import re


class FieldSet(object):
Expand Down Expand Up @@ -219,7 +216,7 @@ def _validate_field(self, field_value):
:returns: validated value
:rtype: str
'''
if not isinstance(field_value, six.string_types):
if not isinstance(field_value, str):
raise FieldSet.Error(
'Field "{}" is not a string'.format(self._name)
)
Expand All @@ -242,7 +239,7 @@ def _validate_pattern(self, option_value, field_value):
least one pattern matches validation is passing
'''
res = None
if isinstance(option_value, six.string_types):
if isinstance(option_value, str):
res = re.findall(option_value, field_value, re.IGNORECASE)
else:
for pattern in option_value:
Expand Down
5 changes: 1 addition & 4 deletions restea/formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
import json
import time

import six


_formatter_registry = {}


Expand Down Expand Up @@ -33,7 +30,7 @@ def __init__(cls, name, bases, dict):
_formatter_registry[cls.name] = cls


class BaseFormatter(six.with_metaclass(FormatterRegistry)):
class BaseFormatter(metaclass=FormatterRegistry):
'''
BaseFormatter is base class for different serialization formats
'''
Expand Down
8 changes: 2 additions & 6 deletions restea/resource.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
from __future__ import unicode_literals

import collections
import collections.abc

import six

import restea.errors as errors
import restea.formats as formats
import restea.fields as fields
import restea.formats as formats


class Resource(object):
Expand Down Expand Up @@ -282,7 +278,7 @@ def _add_available_methods_to_response_headers(self):

@classmethod
def _stream_http_method_and_restea_method(cls):
for http_method, method_names in six.iteritems(cls.method_map):
for http_method, method_names in cls.method_map.items():
if isinstance(method_names, tuple):
for method_name in method_names:
yield http_method, method_name
Expand Down
8 changes: 0 additions & 8 deletions setup.cfg

This file was deleted.

Loading