Skip to content

Commit

Permalink
Merge pull request #242 from Haidra-Org/main
Browse files Browse the repository at this point in the history
feat: API models/fields as of sept 14 2024
  • Loading branch information
tazlin authored Sep 13, 2024
2 parents eec9ff6 + 372400b commit 56f7437
Show file tree
Hide file tree
Showing 19 changed files with 148 additions and 14 deletions.
11 changes: 11 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,14 @@

* The `AI_HORDE_DEV_URL` environment variable overrides `AI_HORDE_URL`. This is useful for testing changes locally.
* pytest files which end in `_api_calls.py` run last, and never run during the CI. It is currently incumbent on individual developers to confirm that these tests run successfully locally. In the future, part of the CI will be to spawn an AI-Horde and worker instances and test it there.


## When the API adds an endpoint or changes a model
With the top level directory (the one that contains `pyproject.toml`) as your working directory:
```python
python horde_sdk/scripts/write_all_payload_examples_for_tests.py
python horde_sdk/scripts/write_all_response_examples_for_tests.py
```
This will update the data found in `tests/test_data/` from the default horde URL, or if any of the override environment variables are set, from there.

Be sure to run the test suite (without any `*_api_calls.py` tests) after.
42 changes: 34 additions & 8 deletions docs/request_field_names_and_descriptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,12 @@
"types": [
"bool"
]
},
"extra_slow_workers": {
"description": "Whether to use the super slow workers.",
"types": [
"bool"
]
}
},
"AlchemyDeleteRequest": {
Expand Down Expand Up @@ -443,6 +449,12 @@
"bool"
]
},
"extra_slow_workers": {
"description": "When True, allows extra slow workers to pick up this request.",
"types": [
"bool"
]
},
"workers": {
"description": "A list of worker IDs to use for this request. If empty, any worker can pick up the request. Using this incurs\nand extra kudos cost.",
"types": [
Expand Down Expand Up @@ -596,15 +608,13 @@
"models": {
"description": "The models this worker can generate.",
"types": [
"list[str]",
"None"
"list[str]"
]
},
"name": {
"description": "The Name of the Worker.",
"types": [
"str",
"None"
"str"
]
},
"nsfw": {
Expand Down Expand Up @@ -714,6 +724,18 @@
"types": [
"bool"
]
},
"extra_slow_worker": {
"description": "Marks the worker as extra slow.",
"types": [
"bool"
]
},
"limit_max_steps": {
"description": "Prevents the worker picking up jobs with more steps than the model average.",
"types": [
"bool"
]
}
},
"ImageGenerateStatusRequest": {
Expand Down Expand Up @@ -1192,6 +1214,12 @@
"bool"
]
},
"extra_slow_workers": {
"description": "When True, allows extra slow workers to pick up this request.",
"types": [
"bool"
]
},
"workers": {
"description": "A list of worker IDs to use for this request. If empty, any worker can pick up the request. Using this incurs\nand extra kudos cost.",
"types": [
Expand Down Expand Up @@ -1310,15 +1338,13 @@
"models": {
"description": "The models this worker can generate.",
"types": [
"list[str]",
"None"
"list[str]"
]
},
"name": {
"description": "The Name of the Worker.",
"types": [
"str",
"None"
"str"
]
},
"nsfw": {
Expand Down
7 changes: 7 additions & 0 deletions docs/response_field_names_and_descriptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,13 @@
}
},
"UserDetailsResponse": {
"active_generations": {
"description": "The active generations this user has requested.",
"types": [
"horde_sdk.ai_horde_api.apimodels._users.ActiveGenerations",
"None"
]
},
"admin_comment": {
"description": "(Privileged) Comments from the horde admins about this user.",
"types": [
Expand Down
2 changes: 2 additions & 0 deletions horde_sdk/ai_horde_api/apimodels/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
NewsResponse,
)
from horde_sdk.ai_horde_api.apimodels._users import (
ActiveGenerations,
ContributionsDetails,
ListUsersDetailsRequest,
ListUsersDetailsResponse,
Expand Down Expand Up @@ -181,6 +182,7 @@
"AIHordeGetTermsRequest",
"DocumentFormat",
"HordeDocument",
"ActiveGenerations",
"ContributionsDetails",
"FindUserRequest",
"KudosTransferRequest",
Expand Down
19 changes: 19 additions & 0 deletions horde_sdk/ai_horde_api/apimodels/_users.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from horde_sdk.ai_horde_api.apimodels.base import BaseAIHordeRequest
from horde_sdk.ai_horde_api.endpoints import AI_HORDE_API_ENDPOINT_SUBPATH
from horde_sdk.ai_horde_api.fields import UUID_Identifier
from horde_sdk.consts import _ANONYMOUS_MODEL, HTTPMethod
from horde_sdk.generic_api.apimodels import (
APIKeyAllowedInRequestMixin,
Expand Down Expand Up @@ -94,6 +95,21 @@ class UsageDetails(HordeAPIDataObject):
"""How many images this user has requested."""


@Unhashable
@Unequatable
class ActiveGenerations(HordeAPIDataObject):
"""A list of generations that are currently active for this user."""

text: list[UUID_Identifier] | None = None
"""The IDs of the text generations that are currently active for this user."""

image: list[UUID_Identifier] | None = None
"""The IDs of the image generations that are currently active for this user."""

alchemy: list[UUID_Identifier] | None = None
"""The IDs of the alchemy generations that are currently active for this user."""


@Unhashable
@Unequatable
class UserDetailsResponse(HordeResponseBaseModel):
Expand All @@ -102,6 +118,9 @@ class UserDetailsResponse(HordeResponseBaseModel):
def get_api_model_name(cls) -> str | None:
return "UserDetails"

active_generations: ActiveGenerations | None = None
"""The active generations this user has requested."""

admin_comment: str | None = Field(
default=None,
)
Expand Down
2 changes: 2 additions & 0 deletions horde_sdk/ai_horde_api/apimodels/alchemy/_async.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class AlchemyAsyncRequest(
"""The public URL of the source image or a base64 string to use."""
slow_workers: bool = True
"""Whether to use the slower workers. Costs additional kudos if `False`."""
extra_slow_workers: bool = False
"""Whether to use the super slow workers."""

@field_validator("forms")
def check_at_least_one_form(cls, v: list[AlchemyAsyncRequestFormItem]) -> list[AlchemyAsyncRequestFormItem]:
Expand Down
4 changes: 4 additions & 0 deletions horde_sdk/ai_horde_api/apimodels/generate/_pop.py
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,10 @@ class ImageGenerateJobPopRequest(BaseAIHordeRequest, APIKeyAllowedInRequestMixin
"""Whether this worker can generate using SDXL controlnets."""
allow_lora: bool = False
"""Whether this worker can generate using Loras."""
extra_slow_worker: bool = False
"""Marks the worker as extra slow."""
limit_max_steps: bool = False
"""Prevents the worker picking up jobs with more steps than the model average."""

@override
@classmethod
Expand Down
6 changes: 6 additions & 0 deletions horde_sdk/ai_horde_worker/bridge_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ class ImageWorkerBridgeData(SharedHordeBridgeData):
allow_lora: bool = False
"""Whether to allow the use of LoRA."""

extra_slow_worker: bool = False
"""Marks the worker as extra slow."""

limit_max_steps: bool = False
"""Prevents the worker picking up jobs with more steps than the model average."""

max_lora_cache_size: int = Field(
default=10,
ge=10,
Expand Down
2 changes: 2 additions & 0 deletions horde_sdk/generic_api/apimodels.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,8 @@ class RequestUsesWorkerMixin(HordeAPIDataObject):
which can increase speed but adds more risk!"""
slow_workers: bool = True
"""When True, allows slower workers to pick up this request. Disabling this incurs an extra kudos cost."""
extra_slow_workers: bool = False
"""When True, allows extra slow workers to pick up this request."""
workers: list[str] = Field(default_factory=list)
"""A list of worker IDs to use for this request. If empty, any worker can pick up the request. Using this incurs
and extra kudos cost."""
Expand Down
3 changes: 3 additions & 0 deletions tests/ai_horde_api/test_ai_horde_api_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ def test_ImageGenerateAsyncRequest(ai_horde_api_key: str) -> None:
nsfw=True,
trusted_workers=False,
slow_workers=False,
extra_slow_workers=False,
workers=[],
censor_nsfw=False,
source_image="test source image (usually base64)",
Expand Down Expand Up @@ -125,6 +126,7 @@ def test_ImageGenerateAsyncRequest(ai_horde_api_key: str) -> None:
assert test_async_request.nsfw is True
assert test_async_request.trusted_workers is False
assert test_async_request.slow_workers is False
assert test_async_request.extra_slow_workers is False
assert test_async_request.workers == []
assert test_async_request.censor_nsfw is False
assert test_async_request.source_image == "test source image (usually base64)"
Expand Down Expand Up @@ -167,6 +169,7 @@ def test_ImageGenerateAsyncRequest_unknown_sampler(ai_horde_api_key: str) -> Non
nsfw=True,
trusted_workers=False,
slow_workers=False,
extra_slow_workers=False,
workers=[],
censor_nsfw=False,
source_image="test source image (usually base64)",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"prompt": "a",
"params": {
"sampler_name": "k_dpm_fast",
"sampler_name": "dpmsolver",
"cfg_scale": 7.5,
"denoising_strength": 0.75,
"hires_fix_denoising_strength": 0.75,
"seed": "The little seed that could",
"height": 512,
"width": 512,
Expand Down Expand Up @@ -47,12 +48,15 @@
}
],
"workflow": "qr_code",
"transparent": false,
"steps": 30,
"n": 1
},
"nsfw": false,
"trusted_workers": false,
"validated_backends": true,
"slow_workers": true,
"extra_slow_workers": false,
"censor_nsfw": false,
"workers": [
""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"threads": 1,
"require_upfront_kudos": false,
"amount": 1,
"extra_slow_worker": true,
"max_pixels": 262144,
"blacklist": [
""
Expand All @@ -21,5 +22,6 @@
"allow_post_processing": true,
"allow_controlnet": true,
"allow_sdxl_controlnet": true,
"allow_lora": true
"allow_lora": true,
"limit_max_steps": true
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
},
"softprompt": "a",
"trusted_workers": false,
"validated_backends": true,
"slow_workers": true,
"workers": [
""
Expand All @@ -50,5 +51,6 @@
],
"disable_batching": false,
"allow_downgrade": false,
"webhook": ""
"webhook": "",
"extra_slow_workers": false
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"threads": 1,
"require_upfront_kudos": false,
"amount": 1,
"extra_slow_worker": true,
"max_length": 512,
"max_context_length": 2048,
"softprompts": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@
"sharedkey_ids": [
"00000000-0000-0000-0000-000000000000"
],
"active_generations": {
"text": [
"00000000-0000-0000-0000-000000000000"
],
"image": [
"00000000-0000-0000-0000-000000000000"
],
"alchemy": [
"00000000-0000-0000-0000-000000000000"
]
},
"monthly_kudos": {
"amount": 0,
"last_received": "2021-01-01T00:00:00Z"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{
"payload": {
"sampler_name": "k_dpmpp_2m",
"sampler_name": "k_dpm_adaptive",
"cfg_scale": 7.5,
"denoising_strength": 0.75,
"hires_fix_denoising_strength": 0.75,
"seed": "The little seed that could",
"height": 512,
"width": 512,
Expand Down Expand Up @@ -46,6 +47,7 @@
}
],
"workflow": "qr_code",
"transparent": false,
"prompt": "",
"ddim_steps": 30,
"n_iter": 1,
Expand All @@ -65,6 +67,7 @@
"bridge_version": 0,
"kudos": 0,
"max_pixels": 0,
"step_count": 0,
"unsafe_ip": 0,
"img2img": 0,
"painting": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
{
"date_published": "",
"newspiece": "",
"importance": "Information"
"importance": "Information",
"tags": [
""
],
"title": "",
"more_info_urls": [
""
]
}
]
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[
{
{
"username": "",
"id": 0,
"kudos": 0.0,
Expand All @@ -23,6 +23,17 @@
"sharedkey_ids": [
"00000000-0000-0000-0000-000000000000"
],
"active_generations": {
"text": [
"00000000-0000-0000-0000-000000000000"
],
"image": [
"00000000-0000-0000-0000-000000000000"
],
"alchemy": [
"00000000-0000-0000-0000-000000000000"
]
},
"monthly_kudos": {
"amount": 0,
"last_received": "2021-01-01T00:00:00Z"
Expand Down
Loading

0 comments on commit 56f7437

Please sign in to comment.