Metadata-Version: 2.1
Name: trustspeccli
Version: 0.1.3
Summary: Web Integration Specification, easy and lightweight alternative to OpenAPI
Home-page: https://github.com/wkarwacki/trust
Author: Wojciech Karwacki
Author-email: karwacki.wojciech@gmail.com
Requires-Python: >=3.10,<4.0
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Environment :: Console
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Rust
Classifier: Topic :: Internet
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
Classifier: Topic :: Software Development
Classifier: Topic :: Software Development :: Code Generators
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Dist: trustspecpy (==0.1.3)
Project-URL: Documentation, https://github.com/wkarwacki/trust
Project-URL: Repository, https://github.com/wkarwacki/trust
Description-Content-Type: text/markdown

<p align="center">
  <b>Documentation, source code: <a href="https://github.com/wkarwacki/trust" target="_blank">https://github.com/wkarwacki/trust</a></b>
</p>

---
# Trust Spec

Web integration specification and a set of code generators. The initiative aims to be replacement for OpenAPI, providing unified way to describe data transfer interface and _Trusted_ generation of modern and type-safe code.

## Table of Contents
- [**tldr; I just want to glue my services together**](#i-just-want-to-glue-my-services-together)
- [Specification](#specification)
  - [Overview](#overview)
  - [Common use cases](#common-use-cases)
  - [OpenAPI conversion](#openapi-conversion)
- [Server and Client code generation](#server-and-client-code-generation)
  - [Usage](#usage)
    - [With Docker](#with-docker)
    - [Run from source](#run-from-source)
  - [Currently supported generators](#currently-supported-generators)
    - [Experimental generators](#experimental-generators)

## I just want to glue my services together
Install Trust with
```shell
$ pip install trustspeccli
```
and then
```shell
$ trust

Usage: trust <COMMAND>

Commands:
  from-open-api  
  to-open-api    
  generate       
  help           Print this message or the help of the given subcommand(s)

Options:
  -h, --help  Print help
```

- If you already have an OpenAPI spec:
  1. first convert it to Trust spec with `from-open-api` command
  2. and then generate the glue code with `generate` command.

  > :exclamation: Note that you may easily automate the whole process combining the two steps above, however it is recommended to make a migration once and benefit from Trust spec expressiveness in the future.

- If you don't have OpenAPI spec yet, you may start with Trust spec directly.

- Alternatively, if you wish to keep generating code from OpenAPI spec, you may use Trust spec as an intermediate format. In this case, the `to-open-api` command will be useful.


## Specification
Trust specification aims to be an improvement of the current integration standards, [OpenAPI](https://github.com/OAI/OpenAPI-Specification) mostly. The main advantages of Trust spec include:
- **Unambiguity of notation** - meaning that there is most likely only one way to model a given API and only way to interpret the spec
- **It supports generic types** - you may give your own types their own parameters and reuse them in different contexts with different arguments
- **It is minimalistic** - not bloated with redundant useless features, keeps the language as simple as possible
- **It is focused on integration of web systems** - if you need to seamlessly integrate two systems in a typesafe way, you will find Trust spec more useful than OpenAPI
- **It is widely customizable** - by providing a broad set of [handlebars](https://github.com/sunng87/handlebars-rust) helpers you may modify the templates upon which the code is generated to suit your needs
- **It is protocol-agnostic** - although it is designed with HTTP in mind, it can be used to describe any kind of API

Moreover it addresses particular issues existing inherently in OpenAPI with:
- **enclosed Algebraic Data Types** - by design all subtypes of an ADT are kept together, in a single `adt` node

### Overview
(Usage of all below examples and more may be found in [tests](https://github.com/wkarwacki/trust/tree/master/src/lib/test))

When it comes to describing API schemas, Trust spec offers the following data types:
* simple types:
  * `type: bool`, equivalent of `type: boolean` in OpenAPI
  * `type: int`, equivalent of `type: integer` with `format: int64` in OpenAPI
  * `type: dec`, equivalent of `type: number` in OpenAPI
  * `type: str`, equivalent of `type: string` in OpenAPI
  * `type: enum`, equivalent of `type: string` with `enum` in OpenAPI
* complex types:
  * `type: obj`, equivalent of `type: object` in OpenAPI
  * `type: seq`, equivalent of `type: array` in OpenAPI
  * `type: map`, equivalent of `type: object` with `additionalProperties` in OpenAPI
* special types:
  * `type: alias`, equivalent of `$ref` in OpenAPI
  * `type: struct`, equivalent of OpenAPI empty schema i.e. `{}`
  * `type: const`, equivalent of OpenAPI `const` feature

### Common use cases

* Including vars from other types:
  ```yaml
  Parent:
    type: obj
    vars:
      parentVar:
        type: dec
  AnotherParent:
    type: obj
    vars:
      anotherParentVar:
        type: bool
  WithParentsVars:
    type: obj
    mix:
      - path: "defs.Parent"
      - path: "defs.AnotherParent"
    vars:
      ownVar:
        type: int
  ```
  will produce a schema matching:
    ```json
    {
        "parentVar": 1.0,
        "anotherParentVar": true,
        "ownVar": 1
    }
    ```
* Algebraic data type aka "union type"
  ```yaml
  AdtType:
    type: obj
    vars: 
      discriminatorVar:
        type: str
      someOtherVar:
        type: dec
    adt:
      var: discriminatorVar
      map:
        firstSubtype:
          vars:
            firstSubtypeVar:
              type: int
        secondSubtype:
          vars:
            secondSubtypeVar:
              type: bool
  ```
  is interpreted as schema matching:
  ```json
  {
    "discriminatorVar": "firstSubtype",
    "someOtherVar": 1.0,
    "firstSubtypeVar": 1
  }
  ```
  ```json
  {
    "discriminatorVar": "secondSubtype",
    "someOtherVar": 1.0,
    "secondSubtypeVar": true
  }
  ```
  but not matching:
  ```json
  {
    "discriminatorVar": "firstSubtype",
    "someOtherVar": 1.0,
  }
  ```
  ```json
  {
    "discriminatorVar": "nonExistentSubtype",
    "someOtherVar": 1.0,
    "secondSubtypeVar": true
  }
  ```
  ```json
  {
    "discriminatorVar": "secondSubtype",
    "secondSubtypeVar": true
  }
  ```
* Generic types
  ```yaml
  defs:
    SomeNamedString:
      type: str
    ParameterizedType:
      type: obj
      vars:
        varOfParamAbcType:
          param: ParamAbc # to declare a generic type, you need to simply use a 'param' keyword
        varOfParamXyzType:
          param: ParamXyz # similarly to the above, this time with a different name
        anoterVarOfParamXyzType:
          param: ParamXyz # similarly to the above, this time with a different name
    SubtypeOfParameterizedType:
      type: obj
      ext: # extending a generic type
        path: 'defs.ParameterizedType'
        args: # with below type-arguments
          ParamAbc:
            type: bool
          ParamXyz:
            path: 'defs.SomeType'
  ```
  The above is interpreted as types that may be represented by:
  ```java
  interface ParameterizedType<ParamAbc, ParamXyz> { 
    ParamAbc varOfParamAbcType; 
    ParamXyz varOfParamXyzType; 
    ParamXyz anoterVarOfParamXyzType; 
  }
  interface SubtypeOfParameterizedType extends ParameterizedType<Boolean, SomeType> { }
  ```
  in Java-like languages.

### OpenAPI conversion

* Layout of the generated Trust spec may be controlled with `-l` option, which may be set to `tag`. In this case the generated Trust spec will be organized by respective tags used in OpenAPI spec. A popular use case of this feature may be generation of Trust spec from FastAPI-generated OpenAPI schema, like [in the following](https://github.com/wkarwacki/trust/blob/master/test/integration/specs/openapi_fastapi/api.yml#L9) test case.

## Server and Client code generation

### Usage

#### With Docker
Prerequisites:
- [Docker](https://docs.docker.com/engine/install/)
```shell
$ ./docker/build.sh
$ docker run trust
```
#### Run from source
Prerequisites:
- [Rust](https://www.rust-lang.org/tools/install)
```shell
$ cargo run trust
```

### Currently supported generators:
- Python Http Server ([fastapi](https://github.com/tiangolo/fastapi))
- Python Http Client ([httpx](https://github.com/encode/httpx))

#### Experimental generators:
> :exclamation:  not fully implemented, use at your own risk

- Kotlin Http Server ([spring](https://github.com/spring-projects/spring-framework))
- Scala Http Server ([cask](https://github.com/com-lihaoyi/cask))

