diff --git a/.github/workflows/apply-httproute.yaml b/.github/workflows/apply-httproute.yaml new file mode 100644 index 0000000..6a2de75 --- /dev/null +++ b/.github/workflows/apply-httproute.yaml @@ -0,0 +1,38 @@ +name: apply-httproute + +on: + workflow_dispatch: + +jobs: + httproute: + name: apply httproute + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Configure kubeconfig + env: + KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }} + run: | + mkdir -p ~/.kube + echo "${KUBECONFIG_B64}" | base64 -d > ~/.kube/config + + - name: Apply HTTPRoute + run: | + set -euo pipefail + kubectl apply --dry-run=server -f deployment/httproute.yaml -n website + kubectl apply -f deployment/httproute.yaml -n website + + - name: Wait for route to be accepted + run: | + set -euo pipefail + for route in docs docs-redirect; do + for cond in Accepted ResolvedRefs; do + kubectl wait --timeout=60s -n website "httproute/$route" \ + --for=jsonpath="{.status.parents[0].conditions[?(@.type==\"$cond\")].status}"=True + done + done diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b06d5b5..523bd3a 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -130,38 +130,3 @@ jobs: --default-repo=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} \ --build-artifacts build.out.json \ -m ${{ env.MODULE }} - - httproute: - name: apply httproute - needs: deploy - if: github.event_name != 'pull_request' - runs-on: ubuntu-latest - permissions: - contents: read - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Configure kubeconfig - env: - KUBECONFIG_B64: ${{ secrets.KUBECONFIG_B64 }} - run: | - mkdir -p ~/.kube - echo "${KUBECONFIG_B64}" | base64 -d > ~/.kube/config - - - name: Apply HTTPRoute - run: | - set -euo pipefail - kubectl apply --dry-run=server -f deployment/httproute.yaml -n website - kubectl apply -f deployment/httproute.yaml -n website - - - name: Wait for route to be accepted - run: | - set -euo pipefail - for route in docs docs-redirect; do - for cond in Accepted ResolvedRefs; do - kubectl wait --timeout=60s -n website "httproute/$route" \ - --for=jsonpath="{.status.parents[0].conditions[?(@.type==\"$cond\")].status}"=True - done - done diff --git a/.gitignore b/.gitignore index b1c4f82..6a57fed 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ +.claude/* + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] -*$py.class +*$py.class # C extensions *.so diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 39c7522..663ec9d 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -25,7 +25,7 @@ { "label": "serve with dirty reload", "type": "shell", - "command": "mkdocs serve --dirtyreload", + "command": "zensical serve", "options": { "cwd": "${workspaceFolder}" } diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..e69de29 diff --git a/Dockerfile b/Dockerfile index b734dec..5d1a905 100644 --- a/Dockerfile +++ b/Dockerfile @@ -21,14 +21,12 @@ COPY . . # development image FROM base AS dev -# ARG MKDOCS_DIRTY_RELOAD=false -# unfortunately dirty reloading is not fast, so we skip now EXPOSE 8000 -CMD ["/bin/sh", "-c", ". .venv/bin/activate && mkdocs serve -a 0.0.0.0:8000"] +CMD ["/bin/sh", "-c", ". .venv/bin/activate && zensical serve -a 0.0.0.0:8000"] # production image FROM base AS build -RUN . .venv/bin/activate && mkdocs build +RUN . .venv/bin/activate && zensical build FROM nginx:alpine AS prod COPY --from=build /app/site /usr/share/nginx/html diff --git a/docs/UML/drawio/hexagonal-architecture.drawio b/docs/UML/drawio/hexagonal-architecture.drawio index db50ce1..4062dfb 100644 --- a/docs/UML/drawio/hexagonal-architecture.drawio +++ b/docs/UML/drawio/hexagonal-architecture.drawio @@ -1,10 +1,10 @@ - + - + @@ -118,6 +118,24 @@ + + + + + + + + + + + + + + + + + + diff --git a/docs/api-reference/injection/index.md b/docs/api-reference/injection/index.md index 5eaaa51..7be933d 100644 --- a/docs/api-reference/injection/index.md +++ b/docs/api-reference/injection/index.md @@ -4,6 +4,7 @@ options: members: [] show_root_heading: false + show_root_toc_entry: false Each registry below resolves an implementation **by name, on first use**. diff --git a/docs/api-reference/namespaces.md b/docs/api-reference/namespaces.md index d3fb2bb..18d8188 100644 --- a/docs/api-reference/namespaces.md +++ b/docs/api-reference/namespaces.md @@ -1,13 +1,19 @@ # Import Namespaces +These are the important namespaces in the repository. + | Namespace | Description | | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `hololinked.core` | Definition of [`Thing`](thing/index.md) class, [`Property`](property/index.md), [`Action`](action/index.md) and [`Event`](events/index.md) classes, [`StateMachine`](state-machine/state-machine.md), [`Logger`](thing/logger.md) & the [`EventLoop`](eventloop/eventloop.md) that executes operations. | -| `hololinked.serializers` | Serializers for different data formats (JSON, MessagePack, etc.) and [`Serializers`](serializers/index.md) singleton. | +| `hololinked.serializers` | Serializers for different data formats (JSON, MessagePack, etc.) | | `hololinked.server` | Protocol specific server implementations | -| `hololinked.client` | [`ObjectProxy`](clients/object-proxy.md) and protocol specific client implementations, client abstractions and [`ClientFactory`](clients/base.md). | -| `hololinked.param` | Copy of `param` library with implementation specific modifications. | +| `hololinked.client` | [`ObjectProxy`](clients/object-proxy.md), protocol specific client implementations, client abstractions and [`ClientFactory`](clients/base.md). | +| `hololinked.param` | Copy of [`holoviz param`](https://param.holoviz.org/en/docs/latest/index.html) library with implementation specific modifications. | | `hololinked.storage` | Database clients for data persistence. | | `hololinked.metadata` | Device description languages a `Thing` can be described in. `hololinked.metadata.td` holds the W3C Web of Things Thing Description/[ThingModel](td/tm.md) parsing and generation. | -| `hololinked.injection` | Dependency injection layer. Holds the lazy adapter registries — `Serializers`, `SchemaValidators`, `StorageBackends` and `MetadataFormats` — that resolve an implementation by name on first use. | +| `hololinked.injection` | Dependency injection layer, holds the lazy adapter registries like `Serializers`, `SchemaValidators`, `StorageBackends` and `MetadataFormats` that resolve an implementation by name on first use. | | `hololinked.schema_validators` | Validators that check property, action and event payloads against a schema (JSON Schema, fastjsonschema, pydantic). | + +A [hexagonal architecture](../design/hexagonal-architecture.md) is followed with `hololinked.core` being the important part of the repository. + +Hexagonal architecture diagram \ No newline at end of file diff --git a/docs/api-reference/protocols/http/config.md b/docs/api-reference/protocols/http/config.md index 89e64ef..1cfb90c 100644 --- a/docs/api-reference/protocols/http/config.md +++ b/docs/api-reference/protocols/http/config.md @@ -20,7 +20,7 @@ - thing_description_service Pass these as a plain dictionary to the `config` argument of -[`HTTPServer`](index.md) — not as a `RuntimeConfig` instance: +[`HTTPServer`](index.md), not as a `RuntimeConfig` instance: ```python HTTPServer(config=dict(cors=True, property_handler=MyPropertyHandler)) diff --git a/docs/api-reference/protocols/zmq/messaging-contract/headers.md b/docs/api-reference/protocols/zmq/messaging-contract/headers.md index a4ff014..e199c5e 100644 --- a/docs/api-reference/protocols/zmq/messaging-contract/headers.md +++ b/docs/api-reference/protocols/zmq/messaging-contract/headers.md @@ -1,8 +1,13 @@ # Headers ::: hololinked.server.zmq.message.RequestHeader - + options: + heading_level: 2 + ::: hololinked.server.zmq.message.ResponseHeader + options: + heading_level: 2 ::: hololinked.server.zmq.message.EventHeader - + options: + heading_level: 2 diff --git a/docs/api-reference/server/index.md b/docs/api-reference/server/index.md index 2e1a301..34a54a3 100644 --- a/docs/api-reference/server/index.md +++ b/docs/api-reference/server/index.md @@ -3,14 +3,11 @@ ::: hololinked.server options: show_root_heading: false + show_root_toc_entry: false members: false ## Entry points -`run()` and `stop()` knows no protocol in particular — they take already-constructed servers and -drive their lifecycle. Use them when you build servers yourself; `Thing.run(access_points=...)` is -the shorthand that calls `run()`. - ::: hololinked.server.run options: show_root_heading: true diff --git a/docs/api-reference/thing/bases/remote-invokable.md b/docs/api-reference/thing/bases/remote-invokable.md index 7f3550a..f4d9e9a 100644 --- a/docs/api-reference/thing/bases/remote-invokable.md +++ b/docs/api-reference/thing/bases/remote-invokable.md @@ -1,3 +1,3 @@ -::: hololinked.core.thing.RemoteInvokable \ No newline at end of file +::: hololinked.core.meta.RemoteInvokable \ No newline at end of file diff --git a/docs/api-reference/thing/thing-meta.md b/docs/api-reference/thing/thing-meta.md index 5e47d9c..a14d350 100644 --- a/docs/api-reference/thing/thing-meta.md +++ b/docs/api-reference/thing/thing-meta.md @@ -1,3 +1,3 @@ -::: hololinked.core.thing.ThingMeta \ No newline at end of file +::: hololinked.core.meta.ThingMeta \ No newline at end of file diff --git a/docs/assets/hexagonal-architecture.drawio.svg b/docs/assets/hexagonal-architecture.drawio.svg index 0bc229e..9f1d3ed 100644 --- a/docs/assets/hexagonal-architecture.drawio.svg +++ b/docs/assets/hexagonal-architecture.drawio.svg @@ -1,4 +1,4 @@ -
hololinked.core

Thing
Property, Action, Event
RPCServer, EventPublisher
Serializers
Metadata Generator
(ThingModel generator)
storage & database
(JSON, sqlalchemy, mongo)
Protocol Servers
(HTTP, MQTT etc.)
Driven Dependencies
Driving
Dependencies
Payload Validators
(Schema based)
\ No newline at end of file +
hololinked.core

Thing
Property, Action, Event
EventLoop, EventPublisher
Serializers
Metadata Generator
(ThingModel generator)
storage & database
(JSON, sqlalchemy, mongo)
Protocol Servers
(HTTP, MQTT etc.)
Driven Dependencies
Driving
Dependencies
Payload Validators
(Schema based)
BaseSchemaValidator
interface
BaseConfigurationRepository
interface
Metadata
interface
BaseSerializer
interface
Request-Reply (EventLoop)
PubSub
(EventPublisher)
\ No newline at end of file diff --git a/docs/beginners-guide/articles/servers.md b/docs/beginners-guide/articles/servers.md index 3e9b93b..51c5c0b 100644 --- a/docs/beginners-guide/articles/servers.md +++ b/docs/beginners-guide/articles/servers.md @@ -61,7 +61,7 @@ See the [protocols](protocols/general.md) section for more options to serve the All requests to properties and actions are generally queued as the domain of operation under the hood is remote procedure calls (RPC) mediated completely by ZMQ. Therefore, only one request is executed at a time as it is assumed that the hardware normally responds to only one (physical-)operation at a time. -This is **only an assumption** to simplify the programming model, given multiple protocols and to avoid unintended race conditions, both logical and in the physical world. One could override them explicitly using [threaded or async methods](actions.md#threaded--async-actions). +This is **only an assumption** to simplify the programming model, given multiple protocols and to avoid unintended race conditions, both logical and in the physical world. One could override them explicitly using [threaded or async methods](actions.md#threaded-async-actions). It is also expected that the internal state of the python object is not inadvertently affected by running multiple requests at once to different properties or actions. If a single request or operation takes 5-10ms, one can still run 100s of operations per second. More often than not, the requirement of parallel operations is never the bottleneck in hardware control. diff --git a/docs/design/action-descriptors.md b/docs/design/action-descriptors.md index 2b4ebae..7445ead 100644 --- a/docs/design/action-descriptors.md +++ b/docs/design/action-descriptors.md @@ -112,6 +112,6 @@ flowchart TD Z --> Q[End] ``` -This scheduling control may need to be implemented in a separate RPC layer or similar. See the [ZMQ RPC layer](zmq.md) for more details. +This scheduling control may need to be implemented in a separate RPC layer or similar. See the [event loop](eventloop.md) for more details. The payload validation step comes after the scheduling decision, as schedulers have higher precedence in the RPC call stack, although the logic is common. \ No newline at end of file diff --git a/docs/design/eventloop.md b/docs/design/eventloop.md new file mode 100644 index 0000000..16f9456 --- /dev/null +++ b/docs/design/eventloop.md @@ -0,0 +1,32 @@ +# Event Loop + +The main purpose of the [`EventLoop`](../api-reference/eventloop/) is to: + +- add scheduling control for the interaction affordances +- decouple protocol handlers from the actual execution of the interaction affordances +- unify execution across multiple protocols +- maintain standardized behaviour irrespective of the protocol, for example, pushing an event must cause both a HTTP and a MQTT client to receive the same event + +Three types of scheduling are supported: + +- **Synchronous** – the default, blocking until the interaction affordance is completed. +- **Async** – non-blocking and can be scheduled on the current async loop. +- **Threaded** – non-blocking and can be scheduled on a separate thread. + +All supported protocols retrieve information from their request object, which is used to create an [`Operation`](../api-reference/eventloop/operation.md). The `EventLoop` is invoked with the `Operation`, which handles the scheduling and execution of the interaction affordance. The response is sent back to the protocol handler, which returns the response to the client: + +```mermaid +sequenceDiagram + participant Client + participant ProtocolHandler + participant EventLoop + + Client->>ProtocolHandler: Send Request + ProtocolHandler->>EventLoop: Schedule an Operation + EventLoop->>EventLoop: Schedule & Execute Affordance (in its own thread) + EventLoop->>ProtocolHandler: Write Response + ProtocolHandler->>Client: Return Response + Note over EventLoop: --- Parallel Event Flow (Pub/Sub) --- + EventLoop-->>ProtocolHandler: Publish Event (Pub) + ProtocolHandler-->>Client: Forward Event (Pub, protocol specific) +``` \ No newline at end of file diff --git a/docs/design/zmq.md b/docs/design/zmq.md deleted file mode 100644 index 65a41c5..0000000 --- a/docs/design/zmq.md +++ /dev/null @@ -1,160 +0,0 @@ -# ZMQ RPC Broker - -The main purpose of the RPC broker is to: - -- add scheduling control for the interaction affordances -- decouple protocol handlers (a.k.a controllers) from the actual execution of the interaction affordances -- unify execution across multiple protocols -- maintain standardized behaviour irrespective of the protocol, for example, pushing an event must cause both a HTTP and a MQTT client to receive the same event - -Three types of scheduling are supported: - -- **Synchronous** – the default, blocking until the interaction affordance is completed. -- **Async** – non-blocking and can be scheduled on the current async loop. -- **Threaded** – non-blocking and can be scheduled on a separate thread. - -All supported protocols retrieve information from their request object, which is used to create a scheduling message. The message is then sent to the ZMQ RPC Broker, which handles the scheduling and execution of the interaction affordance. The ZMQ server then sends the response back to the protocol handler, which returns the response to the client: - -```mermaid -sequenceDiagram - participant Client - participant ProtocolHandler - participant ZMQServer - participant SharedMemory as SharedMemory(INPROC) - - Client->>ProtocolHandler: Send Request - ProtocolHandler->>SharedMemory: Write Scheduling Message - SharedMemory->>ZMQServer: Receive New Message
(in its own thread,
always non blocking to
receive all messages) - ZMQServer->>ZMQServer: Schedule & Execute Affordance - ZMQServer->>SharedMemory: Write Response - SharedMemory->>ProtocolHandler: Forward Response - ProtocolHandler->>Client: Return Response - Note over ZMQServer,SharedMemory: --- Parallel Event Flow (Pub/Sub) --- - ZMQServer-->>SharedMemory: Publish Event (Pub) - SharedMemory-->>ProtocolHandler: Forward Event (Sub) - ProtocolHandler-->>Client: Forward Event (Pub, protocol specific) -``` - -In a certain way, this is definitely a protocol-to-protocol transfer of request and response, with a minor difference that ZMQ handles this over its `INPROC` transport over threads & shared memory, which is significantly more efficient than TCP-to-TCP communication & adds very little overhead. - -The scheduling message is a simple JSON object, tailored to arbitrary serialization and ZMQ multipart messaging scheme: - -=== "Request Message" - - ```json - { - "type": "object", - "$schema": "http://json-schema.org/draft-07/schema#", - "description": "header of the message", - "properties": { - "senderID" : { - "type": "string", - "description": "id of the sender of the message" - }, - "receiverID" : { - "type": "string", - "description": "id of the receiver of the message" - }, - "messageType" : { - "type": "string", - "description": "type of the message being sent", - "enum": [ - "HANDSHAKE", "OPERATION", "EXIT", "INTERRUPT" - ] - }, - "messageID" : { - "type": "string", - "format": "uuid", - "description": "unique id of the message to correlate with the response" - }, - "serverExecutionContext" : { - "type": "object", - "description": "activities to be taken care by the server while performing the operation", - "properties": { - "oneway": { - "type": "boolean" - }, - "invokationTimeout": { - "type": "number", - "minimum": 0 - }, - "executionTimeout": { - "type": "number", - "minimum": 0 - } - } - }, - "thingID" : { - "type": "string", - "description": "id of the thing on which the operation is to be performed" - }, - "object" : { - "type": "string", - "description" : "a property, action or event - object of the thing on which the operation is to be performed" - }, - "operation" : { - "type": "string", - "description" : "name of the peration to be performed", - "enum" : [ - "readProperty", "writeProperty", "invokeAction", "subscribeEvent", - "unsubscribeEvent", "readMultipleProperties", "writeMultipleProperties" - ] - }, - "payloadContentType" : { - "type": "string", - "description" : "content type of the payload", - "enum" : [ - "application/json", "pickle", "x-msgpack", "text", "text/plain" - ] - }, - "preencodedPayloadContentType" : { - "type": "string", - "description" : "content type of the pre-encoded payload" - }, - "thingExecutionContext" : { - "type": "object", - "description" : "thing execution context while performing the operation", - "properties" : { - "fetchExecutionLogs" : { - "type" : "boolean" - } - } - } - }, - "required": ["messageType", "messageID", "serverExecutionContext"] - } - ``` - -=== "Response Message" - - ```json - { - "type": "object", - "$schema": "http://json-schema.org/draft-07/schema#", - "properties" : { - "messageID" : { - "type": "string", - "format": "uuid", - "description": "unique id of the message to correlate with the request" - }, - "messageType" : { - "type": "string", - "description": "type of the message", - "enum": ["REPLY", "ERROR", "TIMEOUT", - "INVALID_MESSAGE", "EVENT_DISCONNECTED"] - }, - "payloadContentType" : { - "type": "string", - "description" : "content type of the payload", - "enum" : [ - "application/json", "pickle", "x-msgpack", "text", "text/plain" - ] - }, - "preencodedPayloadContentType" : { - "type": "string", - "description" : "content type of the pre-encoded payload" - } - }, - "required": ["messageType", "messageID"] - } - ``` diff --git a/docs/index.md b/docs/index.md index 30494b3..348c860 100644 --- a/docs/index.md +++ b/docs/index.md @@ -90,7 +90,7 @@ Additionally, **state machines** can constrain property and action execution: - _Oscilloscope_ - Cannot start a new measurement while one is ongoing - _Camera_ - Cannot change exposure time while capturing video -#### Benefits you get when you use hololinked: +## Benefits you get when you use hololinked - technology independent and technology extensible architecture -> handles technology changes. - its not a solution that uses "different set of technologies to solve the same problem". It solves a problem irrespective of the underlying technologies. AI included. You chose the tech stack or extend it with your stack (PRs welcome for new tech adapters and new features). diff --git a/docs/introduction/security-scanning.md b/docs/introduction/security-scanning.md index b1c1891..78709f3 100644 --- a/docs/introduction/security-scanning.md +++ b/docs/introduction/security-scanning.md @@ -1,6 +1,6 @@ # Scanning -## Bandit +## bandit You can always access the latest security scan results from the Bandit SAST tool in the CI pipeline job of the [main branch](https://github.com/hololinked-dev/hololinked/actions/workflows/ci-pipeline.yml?query=branch%3Amain). diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css index 69e9596..fba9b3e 100644 --- a/docs/stylesheets/extra.css +++ b/docs/stylesheets/extra.css @@ -4,12 +4,13 @@ text-align: justify; } -.md-main[data-md-color-scheme="light"] { - background-color: antiquewhite; +/* Reading area background. */ +[data-md-color-scheme="default"] .md-main { + background-color: #f9f9f9; } -.md-main[data-md-color-scheme="dark"] { - background-color: #1e1e1e; +[data-md-color-scheme="slate"] .md-main { + background-color: #011627; } .hidden-heading { @@ -126,4 +127,25 @@ /* Optional polish */ .md-nav__link--active { font-weight: 700; } /* make current item pop */ -.md-nav__link code { font-family: inherit; } /* keep code fragments consistent in TOCs */ \ No newline at end of file +.md-nav__link code { font-family: inherit; } /* keep code fragments consistent in TOCs */ + +[data-md-color-scheme="default"] .md-header, +[data-md-color-scheme="default"] .md-tabs { + background-color: #ffec3d; + color: #000000de; +} + +[data-md-color-scheme="slate"] .md-header, +[data-md-color-scheme="slate"] .md-tabs { + background-color: #795548; + color: #ffffff; +} + +/* Darker bottom edge on the app bar. */ +[data-md-color-scheme="default"] .md-tabs { + box-shadow: 0 -0.05rem 0 inset rgba(0, 0, 0, 0.32); +} + +[data-md-color-scheme="slate"] .md-tabs { + box-shadow: 0 -0.05rem 0 inset rgba(0, 0, 0, 0.45); +} diff --git a/mkdocs.yml b/mkdocs.yml index ee1cf57..bf87aad 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -70,20 +70,15 @@ nav: - QueuedScheduler: api-reference/eventloop/schedulers/queued-scheduler.md - ThreadedScheduler: api-reference/eventloop/schedulers/threaded-scheduler.md - AsyncScheduler: api-reference/eventloop/schedulers/async-scheduler.md - - Clients: - - ClientFactory: api-reference/clients/base.md - - ObjectProxy: api-reference/clients/object-proxy.md - - Abstractions: - - ConsumedThingAction: api-reference/clients/bases/cta.md - - ConsumedThingProperty: api-reference/clients/bases/ctp.md - - ConsumedThingEvent: api-reference/clients/bases/cte.md - - SSE: api-reference/clients/bases/sse.md - - Utils: api-reference/clients/bases/utils.md - - Security: - - Basic: api-reference/clients/security/basic.md - - API Key: api-reference/clients/security/apikey.md - - OIDC Direct Access Grant: api-reference/clients/security/oidc.md + - Interfaces: + - Ports: api-reference/interfaces/index.md + - BaseSerializer: api-reference/interfaces/serializer.md + - BaseSchemaValidator: api-reference/interfaces/schema-validator.md + - BaseConfigurationRepository: api-reference/interfaces/configuration-repository.md + - Metadata: api-reference/interfaces/metadata.md + - BaseProtocolServer: api-reference/interfaces/protocol-server.md - Servers: + - run: api-reference/server/index.md - HTTP: - HTTPServer: api-reference/protocols/http/index.md - Runtime Configuration: api-reference/protocols/http/config.md @@ -120,21 +115,19 @@ nav: - Security: - Bcrypt: api-reference/protocols/security/bcrypt.md - Argon2: api-reference/protocols/security/argon2.md - - Server: api-reference/server/index.md - - Configuration: api-reference/global-config.md - - Interfaces: - - Ports: api-reference/interfaces/index.md - - BaseSerializer: api-reference/interfaces/serializer.md - - BaseSchemaValidator: api-reference/interfaces/schema-validator.md - - BaseConfigurationRepository: api-reference/interfaces/configuration-repository.md - - Metadata: api-reference/interfaces/metadata.md - - BaseProtocolServer: api-reference/interfaces/protocol-server.md - - Dependency Injection: - - Adapter Registries: api-reference/injection/index.md - - SchemaValidators: api-reference/injection/schema-validators.md - - StorageBackends: api-reference/injection/storage-backends.md - - MetadataFormats: api-reference/injection/metadata-formats.md - - ProtocolServers: api-reference/injection/protocol-servers.md + - Clients: + - ClientFactory: api-reference/clients/base.md + - ObjectProxy: api-reference/clients/object-proxy.md + - Abstractions: + - ConsumedThingAction: api-reference/clients/bases/cta.md + - ConsumedThingProperty: api-reference/clients/bases/ctp.md + - ConsumedThingEvent: api-reference/clients/bases/cte.md + - SSE: api-reference/clients/bases/sse.md + - Utils: api-reference/clients/bases/utils.md + - Security: + - Basic: api-reference/clients/security/basic.md + - API Key: api-reference/clients/security/apikey.md + - OIDC Direct Access Grant: api-reference/clients/security/oidc.md - Schema Validators: - JSONSchemaValidator: api-reference/schema-validators/json-schema.md - FastJSONSchemaValidator: api-reference/schema-validators/fast-json-schema.md @@ -154,19 +147,27 @@ nav: - BaseDB: api-reference/storage/bases.md - Configuration: api-reference/storage/config.md - Models: api-reference/storage/models.md - # - Thing Descriptions: - # - Interaction Affordances: - # - InteractionAffordance: api-reference/td/interaction_affordance/interaction_affordance.md - # - PropertyAffordance: api-reference/td/interaction_affordance/property_affordance.md - # - ActionAffordance: api-reference/td/interaction_affordance/action_affordance.md - # - EventAffordance: api-reference/td/interaction_affordance/event_affordance.md - # - DataSchema: api-reference/td/data_schema.md - # - Thing Model: api-reference/td/tm.md - # - Form: api-reference/td/form.md - # - Metadata: api-reference/td/metadata.md - # - Security Definitions: api-reference/td/security.md - # - Bases: - # - Schema: api-reference/td/bases/schema.md + - Metadata/API Formats: + - Thing Descriptions: + - Interaction Affordances: + - InteractionAffordance: api-reference/td/interaction_affordance/interaction_affordance.md + - PropertyAffordance: api-reference/td/interaction_affordance/property_affordance.md + - ActionAffordance: api-reference/td/interaction_affordance/action_affordance.md + - EventAffordance: api-reference/td/interaction_affordance/event_affordance.md + - DataSchema: api-reference/td/data_schema.md + - Thing Model: api-reference/td/tm.md + - Form: api-reference/td/form.md + - Metadata: api-reference/td/metadata.md + - Security Definitions: api-reference/td/security.md + - Bases: + - Schema: api-reference/td/bases/schema.md + - Configuration: api-reference/global-config.md + - Dependency Injection: + - Adapter Registries: api-reference/injection/index.md + - SchemaValidators: api-reference/injection/schema-validators.md + - StorageBackends: api-reference/injection/storage-backends.md + - MetadataFormats: api-reference/injection/metadata-formats.md + - ProtocolServers: api-reference/injection/protocol-servers.md # Examples # - Examples: # - Energy Meter: examples/energy-meter.md @@ -185,7 +186,7 @@ nav: - Metaclasses: design/metaclasses.md - State Machine: design/state-machine.md - Serialization: design/serialization.md - - ZMQ RPC Layer: design/zmq.md + - Event Loop: design/eventloop.md - Hexagonal Architecture: design/hexagonal-architecture.md theme: @@ -199,7 +200,8 @@ theme: toggle: icon: material/brightness-7 name: Switch to dark mode - primary: yellow + primary: brown + accent: deep orange # Palette toggle for dark mode - media: "(prefers-color-scheme: dark)" @@ -207,7 +209,7 @@ theme: toggle: icon: material/brightness-4 name: Switch to system preference - primary: brown + primary: yellow accent: orange icon: diff --git a/overrides/sitemap.xml b/overrides/sitemap.xml deleted file mode 100644 index 1a5ff6c..0000000 --- a/overrides/sitemap.xml +++ /dev/null @@ -1,13 +0,0 @@ - - -{%- for file in pages -%} -{%- if not file.page.is_link and (file.page.canonical_url or file.page.abs_url) -%} - - {{ (file.page.canonical_url or file.page.abs_url)|e }} - {%- if file.page.update_date %}{{ file.page.update_date }}{% endif -%} - {{ file.page.meta.changefreq|default('weekly') }} - -{%- endif -%} -{%- endfor -%} - - diff --git a/pyproject.toml b/pyproject.toml index a3ae578..31a9764 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,16 +1,15 @@ [project] name = "hololinked-docs-v2" version = "0.1.0" -description = "mkdocs material based documentation for hololinked" +description = "zensical based documentation for hololinked" readme = "README.md" requires-python = ">=3.13" dependencies = [ "mkdocs-autorefs==1.4.2", "mkdocs-git-authors-plugin==0.9.5", "mkdocs-git-revision-date-localized-plugin==1.4.7", - "mkdocs-macros-plugin==1.3.7", - "mkdocs-material==9.6.14", - "mkdocstrings[python]==0.29.1", + "mkdocstrings[python]>=1.0.0", + "zensical==0.0.42", "pydantic==2.11.5", "pip>=25.2", ] @@ -36,4 +35,4 @@ repo = [ ] [tool.uv.sources] -hololinked = { path = "repo/hololinked", editable = true } \ No newline at end of file +hololinked = { path = "repo/hololinked", editable = true } diff --git a/uv.lock b/uv.lock index a8ff4bd..511376d 100644 --- a/uv.lock +++ b/uv.lock @@ -135,19 +135,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4c/1c/ff6546b6c12603d8dd1070aa3c3d273ad4c07f5771689a7b69a550e8c951/backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255", size = 11157 }, ] -[[package]] -name = "backrefs" -version = "5.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6c/46/caba1eb32fa5784428ab401a5487f73db4104590ecd939ed9daaf18b47e0/backrefs-5.8.tar.gz", hash = "sha256:2cab642a205ce966af3dd4b38ee36009b31fa9502a35fd61d59ccc116e40a6bd", size = 6773994 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bf/cb/d019ab87fe70e0fe3946196d50d6a4428623dc0c38a6669c8cae0320fbf3/backrefs-5.8-py310-none-any.whl", hash = "sha256:c67f6638a34a5b8730812f5101376f9d41dc38c43f1fdc35cb54700f6ed4465d", size = 380337 }, - { url = "https://files.pythonhosted.org/packages/a9/86/abd17f50ee21b2248075cb6924c6e7f9d23b4925ca64ec660e869c2633f1/backrefs-5.8-py311-none-any.whl", hash = "sha256:2e1c15e4af0e12e45c8701bd5da0902d326b2e200cafcd25e49d9f06d44bb61b", size = 392142 }, - { url = "https://files.pythonhosted.org/packages/b3/04/7b415bd75c8ab3268cc138c76fa648c19495fcc7d155508a0e62f3f82308/backrefs-5.8-py312-none-any.whl", hash = "sha256:bbef7169a33811080d67cdf1538c8289f76f0942ff971222a16034da88a73486", size = 398021 }, - { url = "https://files.pythonhosted.org/packages/04/b8/60dcfb90eb03a06e883a92abbc2ab95c71f0d8c9dd0af76ab1d5ce0b1402/backrefs-5.8-py313-none-any.whl", hash = "sha256:e3a63b073867dbefd0536425f43db618578528e3896fb77be7141328642a1585", size = 399915 }, - { url = "https://files.pythonhosted.org/packages/0c/37/fb6973edeb700f6e3d6ff222400602ab1830446c25c7b4676d8de93e65b8/backrefs-5.8-py39-none-any.whl", hash = "sha256:a66851e4533fb5b371aa0628e1fee1af05135616b86140c9d787a2ffdf4b8fdc", size = 380336 }, -] - [[package]] name = "bcrypt" version = "4.3.0" @@ -422,6 +409,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/8c/f3147f5c4b73e7550fe5f9352eaa956ae838d5c51eb58e7a25b9f3e2643b/decorator-5.2.1-py3-none-any.whl", hash = "sha256:d316bb415a2d9e2d2b3abcc4084c6502fc09240e292cd76a76afc106a1c8e04a", size = 9190 }, ] +[[package]] +name = "deepmerge" +version = "2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a8/3a/b0ba594708f1ad0bc735884b3ad854d3ca3bdc1d741e56e40bbda6263499/deepmerge-2.0.tar.gz", hash = "sha256:5c3d86081fbebd04dd5de03626a0607b809a98fb6ccba5770b62466fe940ff20", size = 19890 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/82/e5d2c1c67d19841e9edc74954c827444ae826978499bde3dfc1d007c8c11/deepmerge-2.0-py3-none-any.whl", hash = "sha256:6de9ce507115cff0bed95ff0ce9ecc31088ef50cbdf09bc90a09349a318b3d00", size = 13475 }, +] + [[package]] name = "defusedxml" version = "0.7.1" @@ -561,21 +557,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515 }, ] -[[package]] -name = "hjson" -version = "3.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/82/e5/0b56d723a76ca67abadbf7fb71609fb0ea7e6926e94fcca6c65a85b36a0e/hjson-3.1.0.tar.gz", hash = "sha256:55af475a27cf83a7969c808399d7bccdec8fb836a07ddbd574587593b9cdcf75", size = 40541 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/7f/13cd798d180af4bf4c0ceddeefba2b864a63c71645abc0308b768d67bb81/hjson-3.1.0-py3-none-any.whl", hash = "sha256:65713cdcf13214fb554eb8b4ef803419733f4f5e551047c9b711098ab7186b89", size = 54018 }, -] - [[package]] name = "hololinked" version = "0.4.0" source = { editable = "repo/hololinked" } dependencies = [ - { name = "aiomqtt" }, { name = "argon2-cffi" }, { name = "bcrypt" }, { name = "cryptography" }, @@ -591,6 +577,7 @@ dependencies = [ [package.optional-dependencies] all = [ + { name = "aiomqtt" }, { name = "fastjsonschema" }, { name = "jsonschema" }, { name = "psycopg2-binary" }, @@ -602,14 +589,15 @@ all = [ [package.metadata] requires-dist = [ - { name = "aiomqtt", specifier = ">=2.4.0" }, + { name = "aiomqtt", marker = "extra == 'mqtt'", specifier = ">=2.4.0" }, + { name = "aiomqtt", marker = "extra == 'protocols'", specifier = ">=2.4.0" }, { name = "argon2-cffi", specifier = ">=23.1.0" }, { name = "bcrypt", specifier = "==4.3.0" }, { name = "cryptography", specifier = ">=46.0.5" }, { name = "fastjsonschema", marker = "extra == 'validators'", specifier = "==2.20.0" }, + { name = "hololinked", extras = ["protocols", "validators", "serializers", "storage"], marker = "extra == 'all'" }, { name = "hololinked", extras = ["sqlalchemy"], marker = "extra == 'postgresql'" }, { name = "hololinked", extras = ["sqlalchemy", "postgresql", "mongo"], marker = "extra == 'storage'" }, - { name = "hololinked", extras = ["zmq", "validators", "serializers", "storage"], marker = "extra == 'all'" }, { name = "httpx", specifier = ">=0.28.1,<29.0" }, { name = "ifaddr", specifier = ">=0.2.0,<0.3" }, { name = "jsonschema", marker = "extra == 'validators'", specifier = ">=4.22.0,<5.0" }, @@ -618,6 +606,7 @@ requires-dist = [ { name = "pydantic", specifier = ">=2.8.0,<3.0.0" }, { name = "pyjwt", specifier = ">=2.11.0" }, { name = "pymongo", marker = "extra == 'mongo'", specifier = ">=4.15.2" }, + { name = "pyzmq", marker = "extra == 'protocols'", specifier = ">=25.1.0,<26.2" }, { name = "pyzmq", marker = "extra == 'zmq'", specifier = ">=25.1.0,<26.2" }, { name = "serpent", marker = "extra == 'serializers'", specifier = ">=1.41,<2.0" }, { name = "sniffio", specifier = ">=1.3.1,<2.0" }, @@ -625,10 +614,11 @@ requires-dist = [ { name = "structlog", specifier = ">=25.5.0" }, { name = "tornado", specifier = ">=6.3.3" }, ] -provides-extras = ["zmq", "validators", "serializers", "sqlalchemy", "postgresql", "mongo", "storage", "all"] +provides-extras = ["zmq", "mqtt", "protocols", "validators", "serializers", "sqlalchemy", "postgresql", "mongo", "storage", "all"] [package.metadata.requires-dev] all = [ + { name = "aiomqtt", specifier = ">=2.4.0" }, { name = "bandit", specifier = ">=1.9.1" }, { name = "faker", specifier = "==37.5.0" }, { name = "fastjsonschema", specifier = "==2.20.0" }, @@ -665,6 +655,7 @@ dev = [ ] scanning = [{ name = "bandit", specifier = ">=1.9.1" }] test = [ + { name = "aiomqtt", specifier = ">=2.4.0" }, { name = "faker", specifier = "==37.5.0" }, { name = "fastjsonschema", specifier = "==2.20.0" }, { name = "jsonschema", specifier = ">=4.22.0,<5.0" }, @@ -690,11 +681,10 @@ dependencies = [ { name = "mkdocs-autorefs" }, { name = "mkdocs-git-authors-plugin" }, { name = "mkdocs-git-revision-date-localized-plugin" }, - { name = "mkdocs-macros-plugin" }, - { name = "mkdocs-material" }, { name = "mkdocstrings", extra = ["python"] }, { name = "pip" }, { name = "pydantic" }, + { name = "zensical" }, ] [package.dev-dependencies] @@ -722,11 +712,10 @@ requires-dist = [ { name = "mkdocs-autorefs", specifier = "==1.4.2" }, { name = "mkdocs-git-authors-plugin", specifier = "==0.9.5" }, { name = "mkdocs-git-revision-date-localized-plugin", specifier = "==1.4.7" }, - { name = "mkdocs-macros-plugin", specifier = "==1.3.7" }, - { name = "mkdocs-material", specifier = "==9.6.14" }, - { name = "mkdocstrings", extras = ["python"], specifier = "==0.29.1" }, + { name = "mkdocstrings", extras = ["python"], specifier = ">=1.0.0" }, { name = "pip", specifier = ">=25.2" }, { name = "pydantic", specifier = "==2.11.5" }, + { name = "zensical", specifier = "==0.0.42" }, ] [package.metadata.requires-dev] @@ -1306,60 +1295,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/53/b6/106fcc15287e7228658fbd0ad9e8b0d775becced0a089cc39984641f4a0f/mkdocs_git_revision_date_localized_plugin-1.4.7-py3-none-any.whl", hash = "sha256:056c0a90242409148f1dc94d5c9d2c25b5b8ddd8de45489fa38f7fa7ccad2bc4", size = 25382 }, ] -[[package]] -name = "mkdocs-macros-plugin" -version = "1.3.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "hjson" }, - { name = "jinja2" }, - { name = "mkdocs" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "python-dateutil" }, - { name = "pyyaml" }, - { name = "super-collections" }, - { name = "termcolor" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/65/61a746c56788867221aebf07fe4b6b4c08ac99cf341fd51d728c89d1456e/mkdocs_macros_plugin-1.3.7.tar.gz", hash = "sha256:17c7fd1a49b94defcdb502fd453d17a1e730f8836523379d21292eb2be4cb523", size = 33466 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/cf/f03331298ee50a4da6fb72ccec79078041158c1f8b5fc24835c1be42232e/mkdocs_macros_plugin-1.3.7-py3-none-any.whl", hash = "sha256:02432033a5b77fb247d6ec7924e72fc4ceec264165b1644ab8d0dc159c22ce59", size = 37799 }, -] - -[[package]] -name = "mkdocs-material" -version = "9.6.14" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "babel" }, - { name = "backrefs" }, - { name = "colorama" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "mkdocs" }, - { name = "mkdocs-material-extensions" }, - { name = "paginate" }, - { name = "pygments" }, - { name = "pymdown-extensions" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/fa/0101de32af88f87cf5cc23ad5f2e2030d00995f74e616306513431b8ab4b/mkdocs_material-9.6.14.tar.gz", hash = "sha256:39d795e90dce6b531387c255bd07e866e027828b7346d3eba5ac3de265053754", size = 3951707 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/a1/7fdb959ad592e013c01558822fd3c22931a95a0f08cf0a7c36da13a5b2b5/mkdocs_material-9.6.14-py3-none-any.whl", hash = "sha256:3b9cee6d3688551bf7a8e8f41afda97a3c39a12f0325436d76c86706114b721b", size = 8703767 }, -] - -[[package]] -name = "mkdocs-material-extensions" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728 }, -] - [[package]] name = "mkdocstrings" -version = "0.29.1" +version = "1.0.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "jinja2" }, @@ -1369,9 +1307,9 @@ dependencies = [ { name = "mkdocs-autorefs" }, { name = "pymdown-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/41/e8/d22922664a627a0d3d7ff4a6ca95800f5dde54f411982591b4621a76225d/mkdocstrings-0.29.1.tar.gz", hash = "sha256:8722f8f8c5cd75da56671e0a0c1bbed1df9946c0cef74794d6141b34011abd42", size = 1212686 } +sdist = { url = "https://files.pythonhosted.org/packages/1d/5d/f888d4d3eb31359b327bc9b17a212d6ef03fe0b0682fbb3fc2cb849fb12b/mkdocstrings-1.0.4.tar.gz", hash = "sha256:3969a6515b77db65fd097b53c1b7aa4ae840bd71a2ee62a6a3e89503446d7172", size = 100088 } wheels = [ - { url = "https://files.pythonhosted.org/packages/98/14/22533a578bf8b187e05d67e2c1721ce10e3f526610eebaf7a149d557ea7a/mkdocstrings-0.29.1-py3-none-any.whl", hash = "sha256:37a9736134934eea89cbd055a513d40a020d87dfcae9e3052c2a6b8cd4af09b6", size = 1631075 }, + { url = "https://files.pythonhosted.org/packages/6e/94/be70f8ee9c45f2f62b39a1f0e9303bc20e138a8f3b8e50ffd89498e177e1/mkdocstrings-1.0.4-py3-none-any.whl", hash = "sha256:63464b4b29053514f32a1dbbf604e52876d5e638111b0c295ab7ed3cac73ca9b", size = 35560 }, ] [package.optional-dependencies] @@ -1561,15 +1499,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469 }, ] -[[package]] -name = "paginate" -version = "0.5.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746 }, -] - [[package]] name = "paho-mqtt" version = "2.1.0" @@ -1879,11 +1808,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.1" +version = "2.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991 } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151 }, ] [[package]] @@ -1897,15 +1826,15 @@ wheels = [ [[package]] name = "pymdown-extensions" -version = "10.15" +version = "10.21.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markdown" }, { name = "pyyaml" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/92/a7296491dbf5585b3a987f3f3fc87af0e632121ff3e490c14b5f2d2b4eb5/pymdown_extensions-10.15.tar.gz", hash = "sha256:0e5994e32155f4b03504f939e501b981d306daf7ec2aa1cd2eb6bd300784f8f7", size = 852320 } +sdist = { url = "https://files.pythonhosted.org/packages/9e/26/d1015444da4d952a1ca487a236b522eb979766f0295a0bd0c5fc089989a9/pymdown_extensions-10.21.3.tar.gz", hash = "sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354", size = 854140 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/d1/c54e608505776ce4e7966d03358ae635cfd51dff1da6ee421c090dbc797b/pymdown_extensions-10.15-py3-none-any.whl", hash = "sha256:46e99bb272612b0de3b7e7caf6da8dd5f4ca5212c0b273feb9304e236c484e5f", size = 265845 }, + { url = "https://files.pythonhosted.org/packages/7e/85/545a951eecc270fcd688288c600017e2050a1aacb56c711d208586d3e470/pymdown_extensions-10.21.3-py3-none-any.whl", hash = "sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6", size = 269002 }, ] [[package]] @@ -2269,27 +2198,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a8/45/a132b9074aa18e799b891b91ad72133c98d8042c70f6240e4c5f9dabee2f/structlog-25.5.0-py3-none-any.whl", hash = "sha256:a8453e9b9e636ec59bd9e79bbd4a72f025981b3ba0f5837aebf48f02f37a7f9f", size = 72510 }, ] -[[package]] -name = "super-collections" -version = "0.5.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "hjson" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b8/05/d1b50919a0d206d77255217d96dea9ab34bd1eb965a21559380c48f9517e/super_collections-0.5.3.tar.gz", hash = "sha256:94c1ec96c0a0d5e8e7d389ed8cde6882ac246940507c5e6b86e91945c2968d46", size = 10178 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/6d/58de58c521e7fb79bceb4da90d55250070bb4adfa3c870b82519a561c79d/super_collections-0.5.3-py3-none-any.whl", hash = "sha256:907d35b25dc4070910e8254bf2f5c928348af1cf8a1f1e8259e06c666e902cff", size = 8436 }, -] - -[[package]] -name = "termcolor" -version = "3.1.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/6c/3d75c196ac07ac8749600b60b03f4f6094d54e132c4d94ebac6ee0e0add0/termcolor-3.1.0.tar.gz", hash = "sha256:6a6dd7fbee581909eeec6a756cff1d7f7c376063b14e4a298dc4980309e55970", size = 14324 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4f/bd/de8d508070629b6d84a30d01d57e4a65c69aa7f5abe7560b8fad3b50ea59/termcolor-3.1.0-py3-none-any.whl", hash = "sha256:591dd26b5c2ce03b9e43f391264626557873ce1d379019786f99b0c2bee140aa", size = 7684 }, -] - [[package]] name = "terminado" version = "0.18.1" @@ -2316,6 +2224,42 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610 }, ] +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866 }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887 }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704 }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628 }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180 }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674 }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976 }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755 }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265 }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726 }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859 }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713 }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084 }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973 }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223 }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973 }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082 }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490 }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263 }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736 }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717 }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461 }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855 }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144 }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683 }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196 }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393 }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583 }, +] + [[package]] name = "tornado" version = "6.3.3" @@ -2456,3 +2400,33 @@ sdist = { url = "https://files.pythonhosted.org/packages/bd/f4/c67440c7fb409a71b wheels = [ { url = "https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl", hash = "sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366", size = 2196503 }, ] + +[[package]] +name = "zensical" +version = "0.0.42" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "deepmerge" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "pyyaml" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/dd/04e89ab92aed1ef9e36c76ef095fb587ffcbe4162aa7f3fe6d63aafade4a/zensical-0.0.42.tar.gz", hash = "sha256:cc346b833868a59412fe8d8498a152be90be9f3d8fb87e1f1a1c2e1146cbae1b", size = 3931093 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/19/2ca4e52769307959f7485d4c5da7b24787339787c1cbc371885cef448e50/zensical-0.0.42-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:bffd7a34b570fa3ccadf1d23babb0f7c4851c6b626e4fc8ed9f21c2eaae85968", size = 12705326 }, + { url = "https://files.pythonhosted.org/packages/2c/82/0832b0d2c0c2800174141d5519a017105d3dace9194e2c29730e7a676adf/zensical-0.0.42-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:ee1a79789f9462ef44a4b6ebbfc8b5bf4b2447607da8bc5b35bc9c4ce4ea2370", size = 12568663 }, + { url = "https://files.pythonhosted.org/packages/ac/87/272b3998322958ca38f09323d2347cb121dfc851477c36962b71319242a5/zensical-0.0.42-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e9a5d508ce8d1b07d8417f0623be476f6b37d445ab4356481a71e613a7979d6", size = 12948460 }, + { url = "https://files.pythonhosted.org/packages/ae/1b/e5f153401f162f48cae2d58e96b95fd39ba5bd1728fb5881a60e502f4e1d/zensical-0.0.42-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9fbc0951a676e48afe7df3a9b2a30958dcf9c426ed2480972d3c04d6de485ba3", size = 12913460 }, + { url = "https://files.pythonhosted.org/packages/9b/4f/5186b4204bdfdf132851b7515a37b9602bfc153fb601db5fb244339bae52/zensical-0.0.42-cp310-abi3-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8f0e96e53f39b9e4b929a25d9df70bd7fa8217166a854e2c8f3185983dd01500", size = 13276704 }, + { url = "https://files.pythonhosted.org/packages/f2/df/b57b5fcc631ac7a4b4c6834d8cf0b88d3fca37c9db42fc6bbf9f097200ed/zensical-0.0.42-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7d586e57436d603e88acd856864f99f0771aef24bf6560b2de238417bd3817c", size = 12987069 }, + { url = "https://files.pythonhosted.org/packages/a3/3a/b326a44a065d98e89b472645ad33037201e3385340c2e6e35627b18ab3fa/zensical-0.0.42-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3c026f023330d67f986a94b68ffd36dc5066882e697e1125c37308d8d684135c", size = 13124195 }, + { url = "https://files.pythonhosted.org/packages/1b/1e/823740a662e357a8826dc8eeb87e06705e64219b2774430bc555f7c53d57/zensical-0.0.42-cp310-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:e5908bc09cf5c1c50c9504241e37f89955daf3e89ba1b9d71c17972578b24804", size = 13182981 }, + { url = "https://files.pythonhosted.org/packages/80/6d/9fe261267ac36a7d57051d790022408e9043bc925c9ad21971a1e5b6c3e8/zensical-0.0.42-cp310-abi3-musllinux_1_2_i686.whl", hash = "sha256:c0bf96b55f0a44e8716bcb334a16380ed56772b555145da775a7d8ac8678cb6f", size = 13332666 }, + { url = "https://files.pythonhosted.org/packages/9b/57/9b0e4f131a7ad15cf1aca081748ea7336c084fb8e16be202a6bed32f595c/zensical-0.0.42-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:47cd99583738a8ab03fac4080741275c56e741a06dc8edfb541f4c1649a5ae69", size = 13270817 }, + { url = "https://files.pythonhosted.org/packages/bb/fd/bdb85cc444e4146e8970a22e48a903bfed5bf83276ad7d755caa415dda64/zensical-0.0.42-cp310-abi3-win32.whl", hash = "sha256:83090e53fba061967ecb3dff81500b1900f288bae108bf54084a2aeb6648ebd0", size = 12256227 }, + { url = "https://files.pythonhosted.org/packages/e0/b9/09d1f735c8e6d3eb61d176ed5ebcf658b65b126d7d4bbc03a7d366a1e17d/zensical-0.0.42-cp310-abi3-win_amd64.whl", hash = "sha256:2e4304e103f9cd5c637045bbae1ff29de3009ab01b16e99c2fd6d4bbceb7a3ee", size = 12486598 }, +]