Skip to content

Commit

Permalink
Move Python libraries from hashintel/hash into labs (#54)
Browse files Browse the repository at this point in the history
  • Loading branch information
TimDiekmann authored Nov 30, 2023
1 parent 9bbae6c commit f2be7a2
Show file tree
Hide file tree
Showing 61 changed files with 10,390 additions and 0 deletions.
1 change: 1 addition & 0 deletions libs/hash-graph-client/python/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
graph_client/models.py linguist-generated=true
1 change: 1 addition & 0 deletions libs/hash-graph-client/python/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
scripts/openapi.bundle.json
606 changes: 606 additions & 0 deletions libs/hash-graph-client/python/LICENSE.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions libs/hash-graph-client/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# HASH Graph client

OpenAPI automatically generated client for HASH Graph.

Due to current limitations in the auto-generation process, only the models are automatically generated.
The client code is manually written.
357 changes: 357 additions & 0 deletions libs/hash-graph-client/python/graph_client/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,357 @@
"""Client for the HASH API."""

from typing import Literal, TypeAlias, TypeVar
from uuid import UUID

import httpx
from pydantic import BaseModel
from yarl import URL

from graph_client.models import (
CreateDataTypeRequest,
CreateEntityRequest,
CreateEntityTypeRequest,
CreatePropertyTypeRequest,
DataTypeQueryToken,
DataTypeStructuralQuery,
EntityMetadata,
EntityQueryToken,
EntityStructuralQuery,
EntityTypeQueryToken,
EntityTypeStructuralQuery,
LoadExternalDataTypeRequest,
LoadExternalEntityTypeRequest,
LoadExternalPropertyTypeRequest,
MaybeListOfOntologyElementMetadata,
OntologyElementMetadata,
PropertyTypeQueryToken,
PropertyTypeStructuralQuery,
Selector,
Subgraph,
UpdateDataTypeRequest,
UpdateEntityRequest,
UpdateEntityTypeRequest,
UpdatePropertyTypeRequest,
)

T = TypeVar("T", bound=BaseModel)

QueryToken: TypeAlias = (
DataTypeQueryToken
| PropertyTypeQueryToken
| EntityTypeQueryToken
| EntityQueryToken
| Selector
| str
| float
)

__all__ = ["GraphClient", "QueryToken", "models"]


async def _send_request(
endpoint: URL,
method: Literal["POST", "PUT"],
body: BaseModel,
actor: UUID,
response_t: type[T],
) -> T:
"""Send a request to the HASH API."""
async with httpx.AsyncClient() as client:
response = await client.request(
method,
str(endpoint),
json=body.model_dump(by_alias=True, mode="json"),
headers={
"X-Authenticated-User-Actor-Id": str(actor),
},
)

response.raise_for_status()

json = response.json()
return response_t.model_validate(json, strict=False)


U = TypeVar("U")


def _assert_not_none(value: U | None) -> U:
"""Assert that the value is not None."""
if value is None:
msg = "value cannot be None"
raise ValueError(msg)

return value


class GraphClient:
"""Low-level implementation of the client for the HASH API."""

base: URL
actor: UUID | None

def __init__(self, base: URL, *, actor: UUID | None = None) -> None:
"""Initialize the client with the base URL."""
self.base = base
self.actor = actor

def _actor(self, override: UUID | None = None) -> UUID:
"""Get the actor for the client."""
actor = override or self.actor
return _assert_not_none(actor)

async def query_entity_types(
self,
query: EntityTypeStructuralQuery,
*,
actor: UUID | None = None,
) -> Subgraph:
"""Query the HASH API for entity types."""
endpoint = self.base / "entity-types" / "query"

return await _send_request(
endpoint,
"POST",
query,
self._actor(actor),
Subgraph,
)

async def load_external_entity_type(
self,
request: LoadExternalEntityTypeRequest,
*,
actor: UUID | None = None,
) -> OntologyElementMetadata:
"""Load an external entity type."""
endpoint = self.base / "entity-types" / "load"

return await _send_request(
endpoint,
"POST",
request,
self._actor(actor),
OntologyElementMetadata,
)

async def create_entity_types(
self,
request: CreateEntityTypeRequest,
*,
actor: UUID | None = None,
) -> MaybeListOfOntologyElementMetadata:
"""Create an entity type."""
endpoint = self.base / "entity-types"

return await _send_request(
endpoint,
"POST",
request,
self._actor(actor),
MaybeListOfOntologyElementMetadata,
)

async def update_entity_type(
self,
request: UpdateEntityTypeRequest,
*,
actor: UUID | None = None,
) -> OntologyElementMetadata:
"""Update an entity type."""
endpoint = self.base / "entity-types"

return await _send_request(
endpoint,
"PUT",
request,
self._actor(actor),
OntologyElementMetadata,
)

async def query_property_types(
self,
query: PropertyTypeStructuralQuery,
*,
actor: UUID | None = None,
) -> Subgraph:
"""Query the HASH API for property types."""
endpoint = self.base / "property-types" / "query"

return await _send_request(
endpoint,
"POST",
query,
self._actor(actor),
Subgraph,
)

async def load_external_property_type(
self,
request: LoadExternalPropertyTypeRequest,
*,
actor: UUID | None = None,
) -> OntologyElementMetadata:
"""Load an external property type."""
endpoint = self.base / "property-types" / "load"

return await _send_request(
endpoint,
"POST",
request,
self._actor(actor),
OntologyElementMetadata,
)

async def create_property_types(
self,
request: CreatePropertyTypeRequest,
*,
actor: UUID | None = None,
) -> MaybeListOfOntologyElementMetadata:
"""Create a property type."""
endpoint = self.base / "property-types"

return await _send_request(
endpoint,
"POST",
request,
self._actor(actor),
MaybeListOfOntologyElementMetadata,
)

async def update_property_type(
self,
request: UpdatePropertyTypeRequest,
*,
actor: UUID | None = None,
) -> OntologyElementMetadata:
"""Update a property type."""
endpoint = self.base / "property-types"

return await _send_request(
endpoint,
"PUT",
request,
self._actor(actor),
OntologyElementMetadata,
)

async def query_data_types(
self,
query: DataTypeStructuralQuery,
*,
actor: UUID | None = None,
) -> Subgraph:
"""Query the HASH API for data types."""
endpoint = self.base / "data-types" / "query"

return await _send_request(
endpoint,
"POST",
query,
self._actor(actor),
Subgraph,
)

async def load_external_data_type(
self,
request: LoadExternalDataTypeRequest,
*,
actor: UUID | None = None,
) -> OntologyElementMetadata:
"""Load an external data type."""
endpoint = self.base / "data-types" / "load"

return await _send_request(
endpoint,
"POST",
request,
self._actor(actor),
OntologyElementMetadata,
)

async def create_data_types(
self,
request: CreateDataTypeRequest,
*,
actor: UUID | None = None,
) -> MaybeListOfOntologyElementMetadata:
"""Create a data type."""
endpoint = self.base / "data-types"

return await _send_request(
endpoint,
"POST",
request,
self._actor(actor),
MaybeListOfOntologyElementMetadata,
)

async def update_data_type(
self,
request: UpdateDataTypeRequest,
*,
actor: UUID | None = None,
) -> OntologyElementMetadata:
"""Update a data type."""
endpoint = self.base / "data-types"

return await _send_request(
endpoint,
"PUT",
request,
self._actor(actor),
OntologyElementMetadata,
)

async def query_entities(
self,
query: EntityStructuralQuery,
*,
actor: UUID | None = None,
) -> Subgraph:
"""Query the HASH API for entities."""
endpoint = self.base / "entities" / "query"

return await _send_request(
endpoint,
"POST",
query,
self._actor(actor),
Subgraph,
)

async def create_entity(
self,
request: CreateEntityRequest,
*,
actor: UUID | None = None,
) -> EntityMetadata:
"""Create an entity."""
endpoint = self.base / "entities"

return await _send_request(
endpoint,
"POST",
request,
self._actor(actor),
EntityMetadata,
)

async def update_entity(
self,
request: UpdateEntityRequest,
*,
actor: UUID | None = None,
) -> EntityMetadata:
"""Update an entity."""
endpoint = self.base / "entities"

return await _send_request(
endpoint,
"PUT",
request,
self._actor(actor),
EntityMetadata,
)
Loading

0 comments on commit f2be7a2

Please sign in to comment.