Skip to content

Commit

Permalink
chore: switch from src/ to flat project layout
Browse files Browse the repository at this point in the history
  • Loading branch information
tazlin committed Jul 12, 2023
1 parent 7203976 commit 3fa5315
Show file tree
Hide file tree
Showing 54 changed files with 127 additions and 128 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ instance/

# Sphinx documentation
docs/_build/
docs/source/_build/


# PyBuilder
target/
Expand Down
21 changes: 21 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Contributing to horde_sdk

Here are a list of code quality tools this project uses:

* [tox](https://tox.wiki/)
- Creates virtual environments for CI or local pytest runs.
- Note that the CI does not current execute calls to the production API by default.
- Run `tox list` or see `tox.ini` for more info
* [pre-commit](https://pre-commit.com/)
- Creates virtual environments for formatting and linting tools
- Run `pre-commit run --all-files` or see `.pre-commit-config.yaml` for more info.
* [black](https://github.com/psf/black)
- Whitespace formatter
* [ruff](https://github.com/astral-sh/ruff)
- Linting rules from a wide variety of selectable rule sets
- See `pyproject.toml` for the rules used.
- See *all* rules availible in rust [here](https://beta.ruff.rs/docs/rules/).
* [mypy](https://mypy-lang.org/)
- Static type safety
- I recommending using the [mypy daemon](https://mypy.readthedocs.io/en/stable/mypy_daemon.html).
- If you are using VSCode, I recommend the `matangover.mypy` extension, which implements this nicely.
10 changes: 2 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,5 @@

With the power of pydantic, you can simplify interfacing with the [AI-Horde's suite of APIs](https://github.com/db0/AI-Horde). Whether you want to request your own images, or roll your own worker software, this package may suit your needs for anything horde related.

## General notes
- Certain API models have attributes which may collide with a python builtin, such as `id` or `type`. In these cases, the attribute has a trailing underscore, as in `id_`. Ingested json still will work with the field 'id' (its a alias).

## AI-Horde
`TODO`

## Ratings API
There is currently some support for the [Image Ratings](https://dbzer0.com/blog/the-image-ratings-are-flooding-in/) API that are rating images from the [DiffusionDB](https://poloclub.github.io/diffusiondb/) dataset. See `example.py` for an idea of how to start.
## Documentation
For detailed documentation, see our [read the docs page](https://horde-sdk.readthedocs.io/en/latest/index.html).
2 changes: 1 addition & 1 deletion examples/ai_horde_api_client.example.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from horde_sdk.ai_horde_api import AIHordeAPIClient
from horde_sdk.ai_horde_api.apimodels import ImageGenerateAsyncRequest
from horde_sdk.generic_api import RequestErrorResponse
from horde_sdk.generic_api.apimodels import RequestErrorResponse


def do_generate_check(ai_horde_api_client: AIHordeAPIClient) -> None:
Expand Down
2 changes: 1 addition & 1 deletion examples/async_ai_horde_api_client_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from horde_sdk.ai_horde_api import AIHordeAPIClient
from horde_sdk.ai_horde_api.apimodels import ImageGenerateAsyncRequest
from horde_sdk.generic_api import RequestErrorResponse
from horde_sdk.generic_api.apimodels import RequestErrorResponse


async def main() -> None:
Expand Down
5 changes: 3 additions & 2 deletions examples/ratings_api_client_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@
import os

import pydantic
from horde_sdk.ratings_api import (

from horde_sdk.ratings_api.apimodels import (
ImageRatingsComparisonTypes,
RatingsAPIClient,
SelectableReturnFormats,
UserValidateRequest,
UserValidateResponse,
UserValidateResponseRecord,
)
from horde_sdk.ratings_api.ratings_client import RatingsAPIClient

# See also in horde_sdk.ratings_api:
# UserCheckRequest,
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
from horde_sdk.ai_horde_api.endpoints import AI_HORDE_BASE_URL
from horde_sdk.ai_horde_api.fields import GenerationID
from horde_sdk.ai_horde_api.metadata import AIHordePathData
from horde_sdk.generic_api import GenericHordeAPIClient, RequestErrorResponse
from horde_sdk.generic_api.apimodels import RequestErrorResponse
from horde_sdk.generic_api.generic_client import GenericHordeAPIClient


class AIHordeAPIClient(GenericHordeAPIClient):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from horde_sdk.ai_horde_api.apimodels._stats import StatsImageModels, StatsModelsResponse
from horde_sdk.ai_horde_api.apimodels._stats import StatsImageModelsRequest, StatsModelsResponse
from horde_sdk.ai_horde_api.apimodels.generate._async import ImageGenerateAsyncRequest, ImageGenerateAsyncResponse
from horde_sdk.ai_horde_api.apimodels.generate._check import ImageGenerateCheckRequest, ImageGenerateCheckResponse
from horde_sdk.ai_horde_api.apimodels.generate._pop import ImageGenerateJobPopRequest, ImageGenerateJobResponse
Expand All @@ -23,7 +23,7 @@
"ImageGenerateStatusRequest",
"ImageGenerateStatusResponse",
"DeleteImageGenerateRequest",
"StatsImageModels",
"StatsImageModelsRequest",
"StatsModelsResponse",
"ImageGenerationJobSubmitRequest",
"ImageGenerationJobSubmitResponse",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@ class StatsModelsResponse(BaseResponse):
v2 API Model: `ImgModelStats`
"""

model_config = {"frozen": True}

day: dict[str, int]
month: dict[str, int]
total: dict[str, int]
Expand All @@ -24,7 +22,7 @@ def get_api_model_name(cls) -> str | None:
return "ImgModelStats"


class StatsImageModels(BaseAIHordeRequest):
class StatsImageModelsRequest(BaseAIHordeRequest):
"""Represents the data needed to make a request to the `/v2/stats/img/models` endpoint."""

@override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@


class BaseAIHordeRequest(BaseRequest):
"""Base class for all AI Horde API requests."""

@override
@classmethod
def get_api_url(cls) -> str:
Expand Down
Empty file.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from pydantic import BaseModel, Field
from typing_extensions import override

from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest
from horde_sdk.ai_horde_api.consts import WORKER_TYPE
from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_URL_Literals
from horde_sdk.ai_horde_api.fields import TeamID, WorkerID
from horde_sdk.consts import HTTPMethod
from horde_sdk.generic_api.apimodels import BaseRequestAuthenticated, BaseResponse, HordeAPIModel
from pydantic import BaseModel, Field
from typing_extensions import override


class TeamDetailsLite(HordeAPIModel):
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Request metadata specific to the AI-Horde API."""
from horde_sdk.generic_api import GenericPathFields
from horde_sdk.generic_api.metadata import GenericPathFields


class AIHordePathData(GenericPathFields):
Expand Down
1 change: 1 addition & 0 deletions horde_sdk/ai_horde_worker/locale_info/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
If you're making changes to the files in this folder, please only **append** entries, and avoid inserting or otherwise altering the order, as it greatly complicates the localizing process.
File renamed without changes.
1 change: 1 addition & 0 deletions horde_sdk/generic_api/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Tools for making or interacting with any horde APIs."""
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@
import abc
import json

from pydantic import BaseModel, Field, field_validator
from pydantic import BaseModel, ConfigDict, Field, field_validator
from typing_extensions import Self, override

from horde_sdk.consts import HTTPMethod, HTTPStatusCode
from horde_sdk.generic_api import GenericAcceptTypes
from horde_sdk.generic_api.endpoints import url_with_path
from horde_sdk.generic_api.metadata import GenericAcceptTypes


class HordeAPIModel(BaseModel, abc.ABC):
"""Base class for all Horde API data models, requests, or responses."""

model_config = ConfigDict(frozen=True)

@classmethod
@abc.abstractmethod
def get_api_model_name(cls) -> str | None:
Expand All @@ -39,8 +41,6 @@ class HordeAPIMessage(HordeAPIModel):
class BaseResponse(HordeAPIMessage):
"""Represents any response from any Horde API."""

model_config = {"frozen": True}

@classmethod
def is_array_response(cls) -> bool:
"""Return whether this response is an array of an internal type."""
Expand Down Expand Up @@ -119,8 +119,6 @@ def get_api_model_name(cls) -> str | None:
class BaseRequest(HordeAPIMessage):
"""Represents any request to any Horde API."""

model_config = {"frozen": True}

@classmethod
@abc.abstractmethod
def get_http_method(cls) -> HTTPMethod:
Expand Down Expand Up @@ -161,7 +159,7 @@ def get_success_status_response_pairs(cls) -> dict[HTTPStatusCode, type[BaseResp

@classmethod
def get_header_fields(cls) -> list[str]:
"""Return a dict of field names from this request that should be sent as header fields.
"""Return a list of field names from this request object that should be sent as header fields.
This is in addition to `GenericHeaderFields`'s values, and possibly the API specific class
which inherits from `GenericHeaderFields`, typically found in `horde_sdk.<api_name>_api.metadata`.
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,6 @@
from pydantic import BaseModel, ValidationError
from strenum import StrEnum

from horde_sdk.generic_api import (
GenericAcceptTypes,
GenericHeaderFields,
GenericPathFields,
GenericQueryFields,
)
from horde_sdk.generic_api.apimodels import (
BaseRequest,
BaseRequestAuthenticated,
Expand All @@ -21,9 +15,17 @@
BaseResponse,
RequestErrorResponse,
)
from horde_sdk.generic_api.metadata import (
GenericAcceptTypes,
GenericHeaderFields,
GenericPathFields,
GenericQueryFields,
)

HordeRequest = TypeVar("HordeRequest", bound=BaseRequest)
"""TypeVar for the request type."""
HordeResponse = TypeVar("HordeResponse", bound=BaseResponse)
"""TypeVar for the response type."""


class _ParsedRequest(BaseModel):
Expand Down
File renamed without changes.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
from pathlib import Path

import requests
from horde_sdk.consts import PAYLOAD_HTTP_METHODS, HTTPMethod, HTTPStatusCode, is_error_status_code
from loguru import logger
from pydantic import BaseModel, Field, model_validator
from strenum import StrEnum

from horde_sdk.consts import PAYLOAD_HTTP_METHODS, HTTPMethod, HTTPStatusCode, is_error_status_code


class SwaggerModelAdditionalProperty(BaseModel):
# TODO: Is this actually a recursive SwaggerModelDefinitionProperty?
Expand Down
3 changes: 3 additions & 0 deletions horde_sdk/localize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
def _L(s: str) -> str:
"""Indicates that the string is displayed to the user and should be localized."""
return s
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@
from typing_extensions import override

from horde_sdk.consts import _UNDEFINED_MODEL, HTTPMethod
from horde_sdk.generic_api import BaseRequestAuthenticated, BaseRequestUserSpecific
from horde_sdk.generic_api.apimodels import BaseRequest, BaseResponse
from horde_sdk.generic_api.apimodels import (
BaseRequest,
BaseRequestAuthenticated,
BaseRequestUserSpecific,
BaseResponse,
)
from horde_sdk.ratings_api.endpoints import RATING_API_BASE_URL, Rating_API_URL_Literals


Expand All @@ -23,8 +27,6 @@ def get_api_url(cls) -> str:
class BaseImageRatingRecord(BaseModel):
"""The information about any image rating result."""

model_config = {"frozen": True}

image: str
"""The URL to the image."""
rating: int
Expand All @@ -40,8 +42,6 @@ class BaseImageRatingRecord(BaseModel):
class ImageRatingResponseSubRecord(BaseModel):
"""A single sub-record in a response from the `/v1/image/ratings` endpoint."""

model_config = {"frozen": True}

username: str
rating: int
artifacts: int | None
Expand All @@ -50,8 +50,6 @@ class ImageRatingResponseSubRecord(BaseModel):
class ImageRatingsResponse(BaseResponse):
"""The representation of the full response from `/v1/image/ratings`."""

model_config = {"frozen": True}

total: int
image: str
image_id: uuid.UUID
Expand All @@ -75,8 +73,6 @@ class UserRatingsResponseSubRecord(BaseImageRatingRecord):
class UserRatingsResponse(BaseResponse):
"""The representation of the full response from `/v1/user/ratings`."""

model_config = {"frozen": True}

total: int
"""The total number of records in this response."""
ratings: list[UserRatingsResponseSubRecord]
Expand All @@ -95,8 +91,6 @@ class UserValidateResponseRecord(BaseImageRatingRecord):
class UserValidateResponse(BaseResponse):
"""The representation of the full response from `/v1/validate/{user_id}`."""

model_config = {"frozen": True}

total: int
"""The total number of records in this response."""
ratings: list[UserValidateResponseRecord]
Expand All @@ -111,7 +105,6 @@ def get_api_model_name(cls) -> str | None:
class UserCheckResponse(BaseResponse):
"""A single record from the `/v1/user/check/` endpoint."""

model_config = {"frozen": True}
ratings_in_timeframe: int
"""The number of ratings this user submitted in the timeframe."""
ratings_per_minute_in_timeframe: float
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Request metadata specific to the Ratings API."""
from enum import auto

from horde_sdk.generic_api import GenericPathFields, GenericQueryFields
from horde_sdk.generic_api.metadata import GenericPathFields, GenericQueryFields


class RatingsAPIPathFields(GenericPathFields):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Definitions to help interact with the Ratings API."""
from horde_sdk.generic_api import GenericHordeAPIClient
from horde_sdk.generic_api.generic_client import GenericHordeAPIClient
from horde_sdk.ratings_api.metadata import RatingsAPIPathFields, RatingsAPIQueryFields


Expand Down
Empty file added horde_sdk/scripts/__init__.py
Empty file.
File renamed without changes.
21 changes: 21 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
site_name: Horde SDK Documentation

plugins:
- search
- awesome-pages
- autorefs
- mkdocstrings:
handlers:
python:
options:
members_order: source
docstring_section_style: list
show_if_no_docstring: true
separate_signature: true
show_signature_annotations: true

theme:
name: material

extra_css:
- stylesheets/extra.css
7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ dependencies = [
"requests",
"StrEnum",
"loguru",
"babel",
"aiohttp",
"aiodns",
]
license = {file = "LICENSE"}
classifiers = [
Expand All @@ -26,6 +29,10 @@ classifiers = [
"Development Status :: 2 - Pre-Alpha",
]


[tool.setuptools.packages.find]
include = ["hordesdk*", "horde_sdk.*"]

[project.urls]
"Homepage" = "https://github.com/Haidra-Org/horde-sdk"

Expand Down
4 changes: 4 additions & 0 deletions requirements.dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@ types-urllib3
tox==4.6.3
pre-commit==3.3.3
pytest-cov
babel
mkdocstrings
mkdocstrings-python
mkgendocs
Loading

0 comments on commit 3fa5315

Please sign in to comment.