generated from Luis/nextjs-python-web-template
Compare commits
322 Commits
45fc4b8b4c
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
102e38988c | ||
|
|
4e7c44eeb5 | ||
|
|
3238cdf36d | ||
|
|
1abbc383ec | ||
| 5a09cc8e31 | |||
|
|
c6e1b8a21d | ||
|
|
afe291c54c | ||
| 6024090f69 | |||
|
|
596e87c31b | ||
|
|
06c55f151b | ||
|
|
04675f5e9e | ||
|
|
b5008306cb | ||
|
|
1b549549c0 | ||
|
|
29aa17ca7c | ||
|
|
e06afab048 | ||
|
|
697d2685f3 | ||
|
|
2f6ad476b3 | ||
|
|
dc04001dca | ||
|
|
3828402865 | ||
|
|
5b64eb4c3f | ||
|
|
eebc7eee20 | ||
|
|
2e787aa386 | ||
|
|
90c6df93f4 | ||
| 374fdfdaea | |||
|
|
a240cfd340 | ||
|
|
eaec0feb96 | ||
|
|
f3ab6e1b45 | ||
|
|
2c79dabce0 | ||
|
|
fd09d73edd | ||
|
|
2000c1444a | ||
|
|
b98c6090af | ||
| 42a25a2eda | |||
| b6b2bfbee5 | |||
| 09f80b1f42 | |||
| 170ada9382 | |||
| a8b472e84d | |||
|
|
cf3fc347de | ||
|
|
1d39ebcddc | ||
|
|
d978e413d5 | ||
| 8d72268922 | |||
|
|
840b3b6972 | ||
|
|
db1591a76e | ||
|
|
1d6ea0ef0c | ||
|
|
711ade4866 | ||
|
|
7779441c87 | ||
|
|
8e92415c34 | ||
|
|
68e2f6d683 | ||
|
|
c03da10e98 | ||
| 60205b3c22 | |||
| da99e71b54 | |||
| b978aabdd6 | |||
| 357568ebcb | |||
| ea2be8b7c7 | |||
| 672c8364bc | |||
| 2b8a9d9316 | |||
| 9b6fc699f2 | |||
| d232510c0e | |||
| dcaecba393 | |||
| 7901712c4c | |||
|
|
48df7352da | ||
|
|
c5c4ab7178 | ||
|
|
22bcbf6819 | ||
|
|
2ab2282116 | ||
| 1c6e33e74f | |||
| 1757bf1952 | |||
| c726e4bb41 | |||
| 8a5232255f | |||
| 674168160e | |||
| fba6dcb70a | |||
| 3c6cbe01e8 | |||
| 5aff0ec6f0 | |||
| 03f6318651 | |||
| 11f4651814 | |||
| 1b433ea314 | |||
| 894081a5c8 | |||
| 1f09701795 | |||
| 2fb2a1d22a | |||
| 6f4bab98c1 | |||
|
|
ea0148fdaf | ||
|
|
7ae1d5f768 | ||
|
|
ec67dd1bac | ||
|
|
522d7eb69a | ||
|
|
07a5a2fc24 | ||
| d54206f43c | |||
| 29ca34aaed | |||
| 79dbefcfe6 | |||
|
|
59e33f3ead | ||
| a21d9c1bae | |||
| 17df0a6ac1 | |||
|
|
047bee93c4 | ||
|
|
3052015a51 | ||
| 01e98d363b | |||
|
|
407f569837 | ||
|
|
51859b148b | ||
|
|
13de134bb0 | ||
|
|
9f03c187f3 | ||
|
|
1db032e932 | ||
|
|
7b2b675c2c | ||
|
|
47700b7bd0 | ||
| e3813555cc | |||
| 36004c6151 | |||
| 957f99a906 | |||
| f957e55aeb | |||
| 92e584cc5c | |||
| 93084c360b | |||
| 4918f84e85 | |||
| 422a3f4da1 | |||
| 1980204e82 | |||
| f46ed02435 | |||
| cb31fd79c8 | |||
| eb5eb1613f | |||
| d2af394fc7 | |||
| 26e594f94b | |||
| dfd7979baf | |||
| a8557ee039 | |||
| eca63cb824 | |||
| 2864ec20cc | |||
| 390ded6dff | |||
| e47b0b4911 | |||
| b8da1db58c | |||
| 7045f945c8 | |||
| 44797a0bc3 | |||
| 52987625c8 | |||
| 8a3a593cc0 | |||
| 0a20931ba6 | |||
| f4cf817bf1 | |||
| 4ae4557602 | |||
| e72846440c | |||
| a51e94fef3 | |||
| e7ec0a593c | |||
| 334bbd3761 | |||
| 9b37b42d3f | |||
|
|
b4a6fe3ce6 | ||
|
|
29dbb57dae | ||
|
|
780088e4e7 | ||
|
|
cf3039b64c | ||
|
|
1e7bbb0aba | ||
|
|
6dcf0a3290 | ||
|
|
f82afe5466 | ||
|
|
485d1636f0 | ||
|
|
a357a274c0 | ||
|
|
f373f9e1a5 | ||
|
|
6eadaffb74 | ||
|
|
ccb34b06d3 | ||
|
|
09fe544d90 | ||
|
|
36492a14c9 | ||
|
|
b01b01a959 | ||
|
|
b679382622 | ||
|
|
d56bad265f | ||
|
|
9b1533836f | ||
|
|
9aa468b84e | ||
| da3dcaae81 | |||
| a0c6dab00a | |||
|
|
7b68e5d401 | ||
|
|
0c9da1c7c5 | ||
|
|
eec0ab7a8a | ||
|
|
7499b1f98d | ||
|
|
901e9746f4 | ||
|
|
28692dfba4 | ||
|
|
e29b7f6670 | ||
|
|
c8fb3c1a27 | ||
|
|
ac44bc1471 | ||
|
|
d7be07406c | ||
|
|
f9400180b0 | ||
|
|
27691b0ea8 | ||
|
|
dabbe2e2d3 | ||
|
|
e6e64452ba | ||
|
|
afea3692c6 | ||
|
|
3ab3b59655 | ||
| 5bd84b8532 | |||
| c28ea2b177 | |||
| 2a9f31394e | |||
| acb84b8f0b | |||
| e22e954a4a | |||
|
|
8fba3e6a5e | ||
| aab8c88fe2 | |||
| f5b7c38451 | |||
| 2aa7dbcf09 | |||
| 5f4eb1f521 | |||
| 1cb81473c3 | |||
|
|
46377f2952 | ||
|
|
2ac57b76a6 | ||
|
|
0fbd24fa11 | ||
| ab3a6d6128 | |||
| b87fe09032 | |||
| 74fbb7890c | |||
| 6535422148 | |||
| bd30682092 | |||
| aa664dfce1 | |||
| 0c9a8349a6 | |||
| 633055010b | |||
| 68b7171852 | |||
| 5fad1e678f | |||
| 824edac9e9 | |||
|
|
8ee14f1a7b | ||
| 85d62aac89 | |||
| 64dac2f967 | |||
| 5c0696b1bf | |||
|
|
2d8ac0cec9 | ||
|
|
88578fe007 | ||
|
|
61261d7ac3 | ||
|
|
5262d83da0 | ||
| fa4fb0356e | |||
| b12201c559 | |||
| f296c01abc | |||
| 6f61e2f266 | |||
|
|
556b386787 | ||
|
|
37d34d4f36 | ||
| c786313d41 | |||
| 9da8ea8910 | |||
|
|
1cfb5f9fa8 | ||
| 0c08cde34c | |||
|
|
129e25e52e | ||
| 4e0346d0a0 | |||
| a93e6019c5 | |||
|
|
0842882320 | ||
|
|
49d74f1ac2 | ||
|
|
01ce85bb15 | ||
|
|
647fc33acd | ||
|
|
10d9b995cb | ||
| 80269832e6 | |||
| 20e6e551d4 | |||
| 7d4d6f59c2 | |||
|
|
c25ac3025c | ||
|
|
f7cf1ff2b2 | ||
|
|
171582e2e7 | ||
|
|
9b4301d783 | ||
|
|
f3096075d2 | ||
|
|
ef74a557e8 | ||
|
|
2c098f4ba0 | ||
|
|
d95c6ba981 | ||
|
|
0f8d4a431c | ||
|
|
cd0d3937c4 | ||
|
|
b89d2df31b | ||
|
|
3d60652cf1 | ||
|
|
0a902a843d | ||
|
|
6f435df7e9 | ||
|
|
8325d80d39 | ||
|
|
35c7702a3e | ||
| 6006ca30d9 | |||
| d9185f39b7 | |||
|
|
51913f015b | ||
| 6734fa859e | |||
| 5a12de2ad2 | |||
| f28634d4c7 | |||
| 313ca288dc | |||
| 6fa2dad6fd | |||
| af288ceb37 | |||
| efebe6171e | |||
| b4a314f0cd | |||
| 1b635d4056 | |||
| 1665182640 | |||
| d1a3a5381a | |||
| 80ccaa83d3 | |||
| 530b397592 | |||
| 9580c9591e | |||
| 2b76da2b6d | |||
| 01df76de10 | |||
|
|
21a4adf83c | ||
|
|
16d0907da8 | ||
|
|
115b758828 | ||
|
|
0ad48e0de6 | ||
| 3167473bca | |||
| 258bf656cf | |||
| b034bd11f1 | |||
| 9d9124e00a | |||
| 026b1a314a | |||
| fe81b59e36 | |||
|
|
3687aa4e40 | ||
|
|
e14b540687 | ||
|
|
2e82186e6d | ||
|
|
3075144244 | ||
|
|
0cea4644c3 | ||
|
|
2b590e9531 | ||
|
|
e93c6bb7ee | ||
|
|
58f252204b | ||
|
|
12c34c33a2 | ||
|
|
417ca354fc | ||
|
|
99821a1f81 | ||
|
|
2b500fa42a | ||
|
|
576298734e | ||
|
|
45fcf35c1b | ||
|
|
b96a150c78 | ||
|
|
64d88244b8 | ||
|
|
7f6eab3408 | ||
|
|
21e71c4ec2 | ||
| ba62081f40 | |||
|
|
f627558103 | ||
|
|
731fff48d1 | ||
|
|
5336367879 | ||
|
|
9179e4c610 | ||
|
|
c53fdb7d86 | ||
| 1044ce3102 | |||
|
|
a1ca943064 | ||
|
|
449a4fa49b | ||
|
|
8746b0ba65 | ||
|
|
d00ac3f3c6 | ||
|
|
9e2ba4df68 | ||
|
|
330b5dce78 | ||
|
|
bda299d45e | ||
|
|
72da175bc2 | ||
|
|
f92461de2c | ||
| 21dfc52acc | |||
| 48bb161b86 | |||
| 07245f4252 | |||
| eaf7754bbf | |||
| 771bdd68db | |||
| ac5c495c0d | |||
| 5ca06973ec | |||
| fde20e9929 | |||
| 4e97beb655 | |||
| 42b2f8de1a | |||
| 1664b88c55 | |||
| 607a9ed1ae | |||
| 498a9e7ae5 | |||
| 6a4c3e27c6 | |||
| 830211fc36 | |||
| add7686ebc | |||
| 22d39dff27 | |||
| 189a20b9eb | |||
| 4700bb0918 | |||
| dfc5146468 |
@@ -9,4 +9,4 @@ jobs:
|
||||
runs-on: nix
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: nix run --refresh github:Mic92/nix-fast-build -- --no-nom
|
||||
- run: nix run --refresh github:Mic92/nix-fast-build -- --no-nom --eval-workers 8
|
||||
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|| echo "$MODIFIED_FILES" | grep -q ".gitea/workflows/ui_assets.yaml"; then
|
||||
|
||||
echo "UI files have changed"
|
||||
./pkgs/ui/nix/update-ui-assets.sh
|
||||
bash ./pkgs/ui/nix/update-ui-assets.sh
|
||||
|
||||
|
||||
# git push if we have a diff
|
||||
@@ -58,7 +58,8 @@ jobs:
|
||||
git commit -am "update ui-assets.nix"
|
||||
|
||||
echo "Current branch: $GITHUB_REF_NAME"
|
||||
git push origin HEAD:$GITHUB_REF_NAME
|
||||
git push origin HEAD:"$GITHUB_REF_NAME"
|
||||
echo "Done uploading"
|
||||
fi
|
||||
else
|
||||
echo "No UI files changed. Skipping asset build and push"
|
||||
|
||||
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
.direnv
|
||||
sql_app.db
|
||||
.coverage.*
|
||||
**/qubeclan
|
||||
**/testdir
|
||||
@@ -14,6 +15,13 @@ __pycache__
|
||||
.coverage
|
||||
.mypy_cache
|
||||
.pytest_cache
|
||||
pkgs.pyproj
|
||||
.reports
|
||||
.ruff_cache
|
||||
htmlcov
|
||||
|
||||
# georgs
|
||||
pkgs/.vs/
|
||||
pkgs/clan-cli/.hypothesis/
|
||||
ui-assets.tar.gz
|
||||
ui-release
|
||||
12
.gitlab-ci.yml
Normal file
12
.gitlab-ci.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
stages:
|
||||
- release
|
||||
|
||||
release:
|
||||
stage: release
|
||||
script:
|
||||
- set -x
|
||||
- ./service-aware-network-front-end/pkgs/clan-cli/push_docker.sh
|
||||
only:
|
||||
- dev
|
||||
tags:
|
||||
- ea
|
||||
185
README.md
185
README.md
@@ -1,6 +1,6 @@
|
||||
# Website Template
|
||||
# Service Aware Network Project Repo
|
||||
|
||||
Welcome to our website template repository! This template is designed to help you and your team build high-quality websites efficiently. We've carefully chosen the technologies to make development smooth and enjoyable. Here's what you can expect from this template:
|
||||
Welcome to our website repository! This repo is designed to build high-quality websites efficiently. We've carefully chosen the technologies to make development smooth and enjoyable.
|
||||
|
||||
**Frontend**: Our frontend is powered by [React NextJS](https://nextjs.org/), a popular and versatile framework for building web applications.
|
||||
|
||||
@@ -10,29 +10,50 @@ Welcome to our website template repository! This template is designed to help yo
|
||||
|
||||
**Dependency Management**: We use the [Nix package manager](https://nixos.org/) to manage dependencies and ensure reproducibility, making your development process more robust.
|
||||
|
||||
## Supported Operating Systems
|
||||
|
||||
- Linux
|
||||
- macOS
|
||||
|
||||
# Getting Started with the Development Environment
|
||||
|
||||
Let's get your development environment up and running:
|
||||
|
||||
1. **Install Nix Package Manager**:
|
||||
|
||||
- You can install the Nix package manager by either [downloading the Nix installer](https://github.com/DeterminateSystems/nix-installer/releases) or running this command:
|
||||
- You can install the Nix package manager by running this command:
|
||||
```bash
|
||||
curl --proto '=https' --tlsv1.2 -sSf -L https://install.determinate.systems/nix | sh -s -- install
|
||||
```
|
||||
|
||||
On Windows Subsystem for Linux (WSL) the installer will fail and tell you what to do. Execute the command from the error message and then afterwards execute:
|
||||
|
||||
```bash
|
||||
sudo echo "experimental-features = nix-command flakes" > '/etc/nix/nix.conf'
|
||||
```
|
||||
|
||||
2. **Install direnv**:
|
||||
|
||||
- Download the direnv package from [here](https://direnv.net/docs/installation.html) or run the following command:
|
||||
- Install the direnv package by running the following command:
|
||||
```bash
|
||||
curl -sfL https://direnv.net/install.sh | bash
|
||||
```
|
||||
|
||||
3. **Clone the Repository and Navigate**:
|
||||
3. **Add direnv to your shell**:
|
||||
|
||||
- Direnv needs to [hook into your shell](https://direnv.net/docs/hook.html) to work.
|
||||
You can do this by executing following command:
|
||||
|
||||
```bash
|
||||
echo 'eval "$(direnv hook zsh)"' >> ~/.zshrc && echo 'eval "$(direnv hook bash)"' >> ~/.bashrc && eval "$SHELL"
|
||||
```
|
||||
|
||||
4. **Clone the Repository and Navigate**:
|
||||
|
||||
- Clone this repository and navigate to it.
|
||||
- If you are under Windows Subystem For Linux (WSL) please clone the repository to the home folder of your Linux. Do NOT clone it onto your Windows machine!
|
||||
|
||||
4. **Allow .envrc**:
|
||||
5. **Allow .envrc**:
|
||||
|
||||
- When you enter the directory, you'll receive an error message like this:
|
||||
```bash
|
||||
@@ -40,7 +61,7 @@ Let's get your development environment up and running:
|
||||
```
|
||||
- Execute `direnv allow` to automatically execute the shell script `.envrc` when entering the directory.
|
||||
|
||||
5. **Build the Backend**:
|
||||
6. **Build the Backend**:
|
||||
|
||||
- Go to the `pkgs/clan-cli` directory and execute:
|
||||
```bash
|
||||
@@ -48,15 +69,26 @@ Let's get your development environment up and running:
|
||||
```
|
||||
- Wait for the backend to build.
|
||||
|
||||
6. **Start the Backend Server**:
|
||||
7. **Start the Backend Server**:
|
||||
|
||||
- To start the backend server, execute:
|
||||
```bash
|
||||
clan webui --reload --no-open --log-level debug
|
||||
clan webui --reload --no-open --log-level debug --populate --emulate
|
||||
```
|
||||
- The server will automatically restart if any Python files change.
|
||||
- The server will automatically restart if any Python files change. Emulated services however will not.
|
||||
- The `--populate` flag will automatically populate the database with dummy data
|
||||
- To look into the endpoints open up a swagger instance by visiting: http://localhost:2979/docs
|
||||
- The `--emulate` flag will automatically run servers the database with dummy data for the fronted to communicate with (ap, dlg, c1 and c2)
|
||||
- To look into the emulated endpoints go to http://localhost:2979/emulate
|
||||
|
||||
7. **Build the Frontend**:
|
||||
8. **Detailed Backend Documentation**
|
||||
|
||||
- For detailed backend documentation go to [pkgs/clan-cli/README.md](pkgs/clan-cli/README.md)
|
||||
- We explain:
|
||||
- How to build and run a docker image
|
||||
- Internal workings of the App
|
||||
|
||||
9. **Build the Frontend**:
|
||||
|
||||
- In a different shell, navigate to the `pkgs/ui` directory and execute:
|
||||
```bash
|
||||
@@ -64,36 +96,25 @@ Let's get your development environment up and running:
|
||||
```
|
||||
- Wait for the frontend to build.
|
||||
|
||||
8. **Start the Frontend**:
|
||||
- To start the frontend, execute:
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
- Access the website by going to [http://localhost:3000](http://localhost:3000).
|
||||
10. **Start the Frontend**:
|
||||
|
||||
- To start the frontend, execute:
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
- Access the website by going to [http://localhost:3000](http://localhost:3000).
|
||||
|
||||
11. **Detailed Frontend Documentation**
|
||||
|
||||
- For detailed frontend documentation go to [pkgs/ui/README.md](pkgs/ui/README.md)
|
||||
|
||||
# Setting Up Your Git Workflow
|
||||
|
||||
Let's set up your Git workflow to collaborate effectively:
|
||||
|
||||
1. **Register Your Gitea Account Locally**:
|
||||
|
||||
- Execute the following command to add your Gitea account locally:
|
||||
```bash
|
||||
tea login add
|
||||
```
|
||||
- Fill out the prompt as follows:
|
||||
- URL of Gitea instance: `https://gitea.gchq.icu`
|
||||
- Name of new Login [gitea.gchq.icu]: `gitea.gchq.icu:7171`
|
||||
- Do you have an access token? No
|
||||
- Username: YourUsername
|
||||
- Password: YourPassword
|
||||
- Set Optional settings: No
|
||||
|
||||
2. **Git Workflow**:
|
||||
|
||||
1. Add your changes to Git using `git add <file1> <file2>`.
|
||||
2. Run `nix fmt` to lint your files.
|
||||
3. Commit your changes with a descriptive message: `git commit -a -m "My descriptive commit message"`.
|
||||
2. Run `nix fmt` to lint your files. This will format your files and make changes!
|
||||
3. Commit your changes and those of nix fmt with a descriptive message: `git commit -a -m "My descriptive commit message"`.
|
||||
4. Make sure your branch has the latest changes from upstream by executing:
|
||||
```bash
|
||||
git fetch && git rebase origin/main --autostash
|
||||
@@ -101,97 +122,3 @@ Let's set up your Git workflow to collaborate effectively:
|
||||
5. Use `git status` to check for merge conflicts.
|
||||
6. If conflicts exist, resolve them. Here's a tutorial for resolving conflicts in [VSCode](https://code.visualstudio.com/docs/sourcecontrol/overview#_merge-conflicts).
|
||||
7. After resolving conflicts, execute `git merge --continue` and repeat step 5 until there are no conflicts.
|
||||
|
||||
3. **Create a Pull Request**:
|
||||
|
||||
- To automatically open a pull request that gets merged if all tests pass, execute:
|
||||
```bash
|
||||
merge-after-ci
|
||||
```
|
||||
|
||||
4. **Review Your Pull Request**:
|
||||
|
||||
- Visit https://gitea.gchq.icu and go to the project page. Check under "Pull Requests" for any issues with your pull request.
|
||||
|
||||
5. **Push Your Changes**:
|
||||
- If there are issues, fix them and redo step 2. Afterward, execute:
|
||||
```bash
|
||||
git push origin HEAD:YourUsername-main
|
||||
```
|
||||
- This will directly push to your open pull request.
|
||||
|
||||
# Debugging
|
||||
|
||||
When working on the backend of your project, debugging is an essential part of the development process. Here are some methods for debugging and testing the backend of your application:
|
||||
|
||||
## Test Backend Locally in Devshell with Breakpoints
|
||||
|
||||
To test the backend locally in a development environment and set breakpoints for debugging, follow these steps:
|
||||
|
||||
1. Run the following command to execute your tests and allow for debugging with breakpoints:
|
||||
```bash
|
||||
pytest -n0 -s --maxfail=1
|
||||
```
|
||||
You can place `breakpoint()` in your Python code where you want to trigger a breakpoint for debugging.
|
||||
|
||||
## Test Backend Locally in a Nix Sandbox
|
||||
|
||||
To run your backend tests in a Nix sandbox, you have two options depending on whether your test functions have been marked as impure or not:
|
||||
|
||||
### Running Tests Marked as Impure
|
||||
|
||||
If your test functions need to execute `nix build` and have been marked as impure because you can't execute `nix build` inside a Nix sandbox, use the following command:
|
||||
|
||||
```bash
|
||||
nix run .#impure-checks
|
||||
```
|
||||
|
||||
This command will run the impure test functions.
|
||||
|
||||
### Running Pure Tests
|
||||
|
||||
For test functions that have not been marked as impure and don't require executing `nix build`, you can use the following command:
|
||||
|
||||
```bash
|
||||
nix build .#checks.x86_64-linux.clan-pytest --rebuild
|
||||
```
|
||||
|
||||
This command will run all pure test functions.
|
||||
|
||||
### Inspecting the Nix Sandbox
|
||||
|
||||
If you need to inspect the Nix sandbox while running tests, follow these steps:
|
||||
|
||||
1. Insert an endless sleep into your test code where you want to pause the execution. For example:
|
||||
|
||||
```python
|
||||
import time
|
||||
time.sleep(3600) # Sleep for one hour
|
||||
```
|
||||
|
||||
2. Use `cntr` and `psgrep` to attach to the Nix sandbox. This allows you to interactively debug your code while it's paused. For example:
|
||||
|
||||
```bash
|
||||
cntr exec -w your_sandbox_name
|
||||
psgrep -a -x your_python_process_name
|
||||
```
|
||||
|
||||
These debugging and testing methods will help you identify and fix issues in your backend code efficiently, ensuring the reliability and robustness of your application.
|
||||
|
||||
# Using this Template
|
||||
|
||||
To make the most of this template:
|
||||
|
||||
1. Set up a new Gitea account named `ui-asset-bot`. Generate an access token with all access permissions and set it under `settings/actions/secrets` as a secret called `BOT_ACCESS_TOKEN`.
|
||||
|
||||
- Also, edit the file `.gitea/workflows/ui_assets.yaml` and change the `BOT_EMAIL` variable to match the email you set for that account. Gitea matches commits to accounts by their email address, so this step is essential.
|
||||
|
||||
2. Create a second Gitea account named `merge-bot`. Edit the file `pkgs/merge-after-ci/default.nix` if the name should be different. Under "Branches," set the main branch to be protected and add `merge-bot` to the whitelisted users for pushing. Set the unprotected file pattern to `**/ui-assets.nix`.
|
||||
|
||||
- Enable the status check for "build / test (pull_request)."
|
||||
|
||||
3. Add both `merge-bot` and `ui-asset-bot` as collaborators.
|
||||
- Set the option to "Delete pull request branch after merge by default."
|
||||
- Also, set the default merge style to "Rebase then create merge commit."
|
||||
|
||||
With this template, you're well-equipped to build and collaborate on high-quality websites efficiently. Happy coding!
|
||||
|
||||
35
flake.lock
generated
35
flake.lock
generated
@@ -7,11 +7,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1696343447,
|
||||
"narHash": "sha256-B2xAZKLkkeRFG5XcHHSXXcP7To9Xzr59KXeZiRf4vdQ=",
|
||||
"lastModified": 1698882062,
|
||||
"narHash": "sha256-HkhafUayIqxXyHH1X8d9RDl1M2CkFgZLjKD3MzabiEo=",
|
||||
"owner": "hercules-ci",
|
||||
"repo": "flake-parts",
|
||||
"rev": "c9afaba3dfa4085dbd2ccb38dfade5141e33d9d4",
|
||||
"rev": "8c9fa2545007b49a5db5f650ae91f227672c3877",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -42,11 +42,11 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1697059129,
|
||||
"narHash": "sha256-9NJcFF9CEYPvHJ5ckE8kvINvI84SZZ87PvqMbH6pro0=",
|
||||
"lastModified": 1700390070,
|
||||
"narHash": "sha256-de9KYi8rSJpqvBfNwscWdalIJXPo8NjdIZcEJum1mH0=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "5e4c2ada4fcd54b99d56d7bd62f384511a7e2593",
|
||||
"rev": "e4ad989506ec7d71f7302cc3067abd82730a4beb",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -56,11 +56,28 @@
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs-for-iosl": {
|
||||
"locked": {
|
||||
"lastModified": 1700515317,
|
||||
"narHash": "sha256-DSnKT3glZCKE0/Rc6ainSJUbUGC248HNKVRSbo9kxkM=",
|
||||
"owner": "Luis-Hebendanz",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "bcd6be7a5ab22c94c775945fb16a61b5867f15d2",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "Luis-Hebendanz",
|
||||
"ref": "iosl",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-parts": "flake-parts",
|
||||
"floco": "floco",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-for-iosl": "nixpkgs-for-iosl",
|
||||
"treefmt-nix": "treefmt-nix"
|
||||
}
|
||||
},
|
||||
@@ -71,11 +88,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1695822946,
|
||||
"narHash": "sha256-IQU3fYo0H+oGlqX5YrgZU3VRhbt2Oqe6KmslQKUO4II=",
|
||||
"lastModified": 1699786194,
|
||||
"narHash": "sha256-3h3EH1FXQkIeAuzaWB+nK0XK54uSD46pp+dMD3gAcB4=",
|
||||
"owner": "numtide",
|
||||
"repo": "treefmt-nix",
|
||||
"rev": "720bd006d855b08e60664e4683ccddb7a9ff614a",
|
||||
"rev": "e82f32aa7f06bbbd56d7b12186d555223dc399d1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
|
||||
floco.url = "github:aakropotkin/floco";
|
||||
floco.inputs.nixpkgs.follows = "nixpkgs";
|
||||
nixpkgs-for-iosl.url = "github:Luis-Hebendanz/nixpkgs/iosl";
|
||||
flake-parts.url = "github:hercules-ci/flake-parts";
|
||||
flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||
treefmt-nix.url = "github:numtide/treefmt-nix";
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
treefmt.settings.formatter.prettier.excludes = [
|
||||
"secrets.yaml"
|
||||
"key.json"
|
||||
"keyfile.json"
|
||||
"**/pkgs/clan-cli/tests/openapi_client/**"
|
||||
];
|
||||
|
||||
treefmt.programs.mypy.enable = true;
|
||||
@@ -25,6 +27,7 @@
|
||||
"pkgs/clan-cli".extraPythonPackages = self'.packages.clan-cli.pytestDependencies;
|
||||
};
|
||||
|
||||
|
||||
treefmt.settings.formatter.nix = {
|
||||
command = "sh";
|
||||
options = [
|
||||
@@ -51,6 +54,7 @@
|
||||
"--" # this argument is ignored by bash
|
||||
];
|
||||
includes = [ "*.py" ];
|
||||
excludes = [ "**/tests/openapi_client/**" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
2
pkgs/clan-cli/.vscode/settings.json
vendored
2
pkgs/clan-cli/.vscode/settings.json
vendored
@@ -18,5 +18,5 @@
|
||||
"python.linting.mypyPath": "mypy",
|
||||
"python.linting.mypyEnabled": true,
|
||||
"python.linting.enabled": true,
|
||||
"python.defaultInterpreterPath": "python"
|
||||
"python.defaultInterpreterPath": "/nix/store/k34qdl5397mwg3k00jsl3xcynij7n0z9-python3-3.11.6-env/bin/python"
|
||||
}
|
||||
@@ -1,34 +1,333 @@
|
||||
# clan-cli
|
||||
# Starting The Backend
|
||||
|
||||
The clan-cli contains the command line interface as well as the graphical webui through the `clan webui` command.
|
||||
|
||||
## Hacking on the cli
|
||||
Start the web ui with
|
||||
|
||||
We recommend setting up [direnv](https://direnv.net/) to load the developement with nix.
|
||||
If you do not have it set up you can also use `nix develop` directly like this:
|
||||
|
||||
```
|
||||
use flake .#clan-cli --builders ''
|
||||
```bash
|
||||
clan webui --reload --no-open --log-level debug --populate --emulate
|
||||
```
|
||||
|
||||
After you can use the local bin wrapper to test things in the cli:
|
||||
- The `--populate` flag will automatically populate the database with dummy data
|
||||
- To look into the endpoints open up a swagger instance by visiting: http://localhost:2979/docs
|
||||
- The `--emulate` flag will automatically run servers the database with dummy data for the fronted to communicate with (ap, dlg, c1 and c2)
|
||||
- To look into the emulated endpoints go to http://localhost:2979/emulate
|
||||
|
||||
```
|
||||
./bin/clan
|
||||
# Using the Uploaded Docker Image
|
||||
|
||||
Pull the image
|
||||
|
||||
```bash
|
||||
docker pull git.tu-berlin.de:5000/internet-of-services-lab/service-aware-network-front-end:latest
|
||||
```
|
||||
|
||||
## Hacking on the webui
|
||||
Run the image
|
||||
|
||||
By default the webui is build from a tarball available https://git.clan.lol/clan/-/packages/generic/ui/.
|
||||
To start a local developement environment instead, use the `--dev` flag:
|
||||
|
||||
```
|
||||
./bin/clan webui --dev
|
||||
```bash
|
||||
docker run -p 127.0.0.1:2979:2979 git.tu-berlin.de:5000/internet-of-services-lab/service-aware-network-front-end:latest
|
||||
```
|
||||
|
||||
This will spawn two webserver, a python one to for the api and a nodejs one that rebuilds the ui on the fly.
|
||||
# API Documentation
|
||||
|
||||
## Run webui directly
|
||||
Api documentation can be found in the folder `pkgs/clan-cli/tests/openapi_client/docs/`
|
||||
For Entity object go to
|
||||
|
||||
- [tests/openapi_client/docs/EntitiesApi.md](tests/openapi_client/docs/EntitiesApi.md)
|
||||
- [tests/openapi_client/docs/EventmessagesApi.md](tests/openapi_client/docs/EventmessagesApi.md)
|
||||
- [tests/openapi_client/docs/ServicesApi.md](tests/openapi_client/docs/ServicesApi.md)
|
||||
- [tests/openapi_client/docs/ResolutionApi.md](tests/openapi_client/docs/ResolutionApi.md)
|
||||
- [tests/openapi_client/docs/RepositoriesApi.md](tests/openapi_client/docs/RepositoriesApi.md)
|
||||
|
||||
# Building a Docker Image if the Frontend Changed
|
||||
|
||||
To build a new docker image when the frontend code and/or backend code changed you first need
|
||||
to get the `GITLAB_TOKEN` go to [repo access tokens](https://git.tu-berlin.de/internet-of-services-lab/service-aware-network-front-end/-/settings/access_tokens) and generate one.
|
||||
|
||||
- Make sure the Gitlab token has access to package registry.
|
||||
|
||||
Then execute
|
||||
|
||||
```bash
|
||||
export GITLAB_TOKEN="<your-access-token>"
|
||||
```
|
||||
|
||||
Afterwards you can execute:
|
||||
|
||||
```bash
|
||||
./build_docker.sh
|
||||
```
|
||||
|
||||
This will create a symlink directory called `result` to a tar.gz docker file. Import it by executing:
|
||||
|
||||
```bash
|
||||
docker load < result
|
||||
```
|
||||
|
||||
And then run the docker file by executing:
|
||||
|
||||
```bash
|
||||
docker run -p 127.0.0.1:2979:2979 clan-docker:latest
|
||||
```
|
||||
|
||||
# Uploading a Docker Image
|
||||
|
||||
You can use the script:
|
||||
|
||||
```bash
|
||||
./push_docker.sh
|
||||
```
|
||||
|
||||
### The Script Explained
|
||||
|
||||
Login to the tu docker image server
|
||||
|
||||
```bash
|
||||
docker login git.tu-berlin.de:5000
|
||||
```
|
||||
|
||||
Tag the imported image
|
||||
|
||||
```bash
|
||||
docker image tag clan-docker:latest git.tu-berlin.de:5000/internet-of-services-lab/service-aware-network-front-end:latest
|
||||
```
|
||||
|
||||
Push the image to the git registry
|
||||
|
||||
```bash
|
||||
docker image push git.tu-berlin.de:5000/internet-of-services-lab/service-aware-network-front-end:latest
|
||||
```
|
||||
|
||||
# Upload UI assets as a package
|
||||
|
||||
To upload the release build UI assets to gitlab as a package
|
||||
first get the `GITLAB_TOKEN`. Go to [repo access tokens](https://git.tu-berlin.de/internet-of-services-lab/service-aware-network-front-end/-/settings/access_tokens) and generate one.
|
||||
|
||||
- Make sure the Gitlab token has access to package registry.
|
||||
|
||||
To upload the UI assets as a package then execute:
|
||||
|
||||
```bash
|
||||
./upload_ui_assets.sh
|
||||
```
|
||||
|
||||
Please commit the changes to ui-assets.nix and push them to the repository.
|
||||
If you want clan webui to use the new ui assets.
|
||||
|
||||
```bash
|
||||
$ git commit -m "Update ui-assets.nix" "$PROJECT_DIR/pkgs/ui/nix/ui-assets.nix"
|
||||
$ git push
|
||||
```
|
||||
|
||||
If you execute `clan webui` the page you will see is a precompiled release version of the UI. This above script will update said precompiled release version. The `./build_docker.sh` script execute this to make sure that the included UI in the docker is up to date.
|
||||
|
||||
### The Script Explained
|
||||
|
||||
If changes to the UI have been made, and you want them to propagate to the docker container and the `clan webui` command edit the file: [../ui/nix/ui-assets.nix](../ui/nix/ui-assets.nix).
|
||||
This is where a release version of the frontend is downloaded and integrated into the cli and the docker build. To do this first execute
|
||||
|
||||
```bash
|
||||
nix build .#ui --out-link ui-release
|
||||
```
|
||||
|
||||
Make a tarball out of it called `ui-assets.tar.gz`
|
||||
|
||||
```bash
|
||||
tar --transform 's,^\.,assets,' -czvf "ui-assets.tar.gz" -C ui-release/result/lib/node_modules/*/out .
|
||||
```
|
||||
|
||||
Upload ui-assets.tar.gz to gitlab.
|
||||
|
||||
```bash
|
||||
curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
|
||||
--upload-file ./ui-assets.tar.gz \
|
||||
"https://git.tu-berlin.de/api/v4/projects/internet-of-services-lab%2Fservice-aware-network-front-end/packages/generic/ui-assets/1.0.0/ui-assets.tar.gz"
|
||||
```
|
||||
|
||||
You can find your uploaded package at the [package registry](https://git.tu-berlin.de/internet-of-services-lab/service-aware-network-front-end/-/packages)
|
||||
|
||||
And export the download url into a variable:
|
||||
|
||||
```
|
||||
export url="https://git.tu-berlin.de/api/v4/projects/internet-of-services-lab%2Fservice-aware-network-front-end/packages/generic/ui-assets/1.0.0/ui-assets.tar.gz"
|
||||
```
|
||||
|
||||
Now execute the command:
|
||||
|
||||
```bash
|
||||
cat > "../ui/nix/ui-assets.nix" <<EOF
|
||||
{ fetchzip }:
|
||||
fetchzip {
|
||||
url = "$url";
|
||||
sha256 = "$(nix-prefetch-url --unpack $url)";
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
And now build the docker image:
|
||||
|
||||
```bash
|
||||
nix build .#clan-docker
|
||||
```
|
||||
|
||||
# Building a Docker Image if only the Backend Changed
|
||||
|
||||
To build a new docker image only when the backend code changed execute:
|
||||
|
||||
```bash
|
||||
nix build .#clan-docker
|
||||
```
|
||||
|
||||
This is much faster then the `./build_docker.sh` script as it needs not to build the frontend and again.
|
||||
This will create a symlink directory called `result` to a tar.gz docker file. Import it by executing:
|
||||
|
||||
```bash
|
||||
docker load < result
|
||||
```
|
||||
|
||||
And then run the docker file by executing:
|
||||
|
||||
```bash
|
||||
docker run -p 127.0.0.1:2979:2979 clan-docker:latest
|
||||
```
|
||||
|
||||
- To change parameters in the generated docker image edit the file :
|
||||
[flake-module.nix at line 22](flake-module.nix)
|
||||
- Documentation on `dockerTools.buildImage` you can find here: https://nix.dev/tutorials/nixos/building-and-running-docker-images.html
|
||||
|
||||
# Auto Generating a Python Client
|
||||
|
||||
For the tests we automatically generate a python client for the API endpoints. To do this execute while inside the `pkgs/clan-cli` folder:
|
||||
|
||||
```bash
|
||||
./bin/gen-python-client
|
||||
```
|
||||
|
||||
This will replace the folder
|
||||
`tests/openapi_client`.
|
||||
|
||||
# Adding dependencies
|
||||
|
||||
**Dependency Management**: We use the [Nix package manager](https://nixos.org/) to manage dependencies and ensure reproducibility, making your development process more robust.
|
||||
|
||||
To add dependencies edit the file [default.nix](default.nix)
|
||||
|
||||
To search for a python dependency named "request" execute:
|
||||
|
||||
```bash
|
||||
nix search nixpkgs#pythonPackages request
|
||||
```
|
||||
|
||||
Add the depdendency at the top of the file
|
||||
|
||||
```nix
|
||||
{
|
||||
, mydep # <--- Add here
|
||||
, websockets
|
||||
, broadcaster
|
||||
, aenum
|
||||
, dateutil
|
||||
, urllib3
|
||||
}:
|
||||
let
|
||||
[...]
|
||||
```
|
||||
|
||||
Add them into this array if they are a python dependency
|
||||
|
||||
```nix
|
||||
dependencies = [
|
||||
argcomplete
|
||||
fastapi
|
||||
uvicorn
|
||||
sqlalchemy
|
||||
websockets
|
||||
broadcaster
|
||||
mydep # <--- Add here
|
||||
];
|
||||
```
|
||||
|
||||
To search for a binary dependency named "firefox" execute:
|
||||
|
||||
```bash
|
||||
nix search nixpkgs firefox
|
||||
```
|
||||
|
||||
Runtime dependency add them into this array:
|
||||
|
||||
```nix
|
||||
runtimeDependencies = [
|
||||
bash
|
||||
nix
|
||||
fakeroot
|
||||
zbar
|
||||
git
|
||||
mypy
|
||||
];
|
||||
```
|
||||
|
||||
# Development environment
|
||||
|
||||
The development environment created by `nix develop` or automatically by `direnv` is located at [shell.nix](shell.nix). The `shellHook` variable execute bash code.
|
||||
|
||||
# Debugging
|
||||
|
||||
When working on the backend of your project, debugging is an essential part of the development process. Here are some methods for debugging and testing the backend of your application:
|
||||
|
||||
## Test Backend Locally in Devshell with Breakpoints
|
||||
|
||||
To test the backend locally in a development environment and set breakpoints for debugging, follow these steps:
|
||||
|
||||
1. Run the following command to execute your tests and allow for debugging with breakpoints:
|
||||
```bash
|
||||
rm -f sql_app.db && pytest -s
|
||||
```
|
||||
You can place `breakpoint()` in your Python code where you want to trigger a breakpoint for debugging.
|
||||
|
||||
## Test Backend Locally in a Nix Sandbox
|
||||
|
||||
To run your backend tests in a Nix sandbox, you have two options depending on whether your test functions have been marked as impure or not:
|
||||
|
||||
### Running Tests Marked as Impure
|
||||
|
||||
If your test functions need to execute `nix build` and have been marked as impure because you can't execute `nix build` inside a Nix sandbox, use the following command:
|
||||
|
||||
```bash
|
||||
nix run .#impure-checks
|
||||
```
|
||||
|
||||
This command will run the impure test functions.
|
||||
|
||||
### Running Pure Tests
|
||||
|
||||
For test functions that have not been marked as impure and don't require executing `nix build`, you can use the following command:
|
||||
|
||||
```bash
|
||||
nix build .#checks.x86_64-linux.clan-pytest --rebuild
|
||||
```
|
||||
|
||||
This command will run all pure test functions.
|
||||
|
||||
### Inspecting the Nix Sandbox
|
||||
|
||||
If you need to inspect the Nix sandbox while running tests, follow these steps:
|
||||
|
||||
1. Insert an endless sleep into your test code where you want to pause the execution. For example:
|
||||
|
||||
```python
|
||||
import time
|
||||
time.sleep(3600) # Sleep for one hour
|
||||
```
|
||||
|
||||
2. Use `cntr` and `psgrep` to attach to the Nix sandbox. This allows you to interactively debug your code while it's paused. For example:
|
||||
|
||||
```bash
|
||||
psgrep -a -x your_python_process_name
|
||||
cntr attach <pid>
|
||||
```
|
||||
|
||||
These debugging and testing methods will help you identify and fix issues in your backend code efficiently, ensuring the reliability and robustness of your application.
|
||||
|
||||
## Run Web UI in VSCode
|
||||
|
||||
Useful for vscode run and debug option
|
||||
|
||||
@@ -53,18 +352,3 @@ Add this `launch.json` to your .vscode directory to have working breakpoints in
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Run locally single-threaded for debugging
|
||||
|
||||
By default tests run in parallel using pytest-xdist.
|
||||
pytest-xdist however breaks `breakpoint()`. To disable it, use this:
|
||||
|
||||
```console
|
||||
pytest -n0 -s
|
||||
```
|
||||
|
||||
You can also run a single test like this:
|
||||
|
||||
```console
|
||||
pytest -n0 -s tests/test_secrets_cli.py::test_users
|
||||
```
|
||||
|
||||
0
pkgs/clan-cli/bin/clan
Executable file → Normal file
0
pkgs/clan-cli/bin/clan
Executable file → Normal file
0
pkgs/clan-cli/bin/clan-config
Executable file → Normal file
0
pkgs/clan-cli/bin/clan-config
Executable file → Normal file
@@ -1,4 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
|
||||
93
pkgs/clan-cli/bin/gen-python-client
Executable file
93
pkgs/clan-cli/bin/gen-python-client
Executable file
@@ -0,0 +1,93 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import sys
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from uvicorn.importer import import_from_string
|
||||
import subprocess
|
||||
import shutil
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
def replace_line_in_file(file_path: Path, pattern: str, replacement: str) -> None:
|
||||
with open(file_path, 'r') as file:
|
||||
content = file.read()
|
||||
updated_content = re.sub(pattern, replacement, content)
|
||||
with open(file_path, 'w') as file:
|
||||
file.write(updated_content)
|
||||
|
||||
def replace_in_directory(*, directory_path: Path, pattern: str, replacement: str) -> None:
|
||||
for root, dirs, files in os.walk(directory_path):
|
||||
for file in files:
|
||||
file_path = Path(os.path.join(root, file))
|
||||
replace_line_in_file(file_path, pattern, replacement)
|
||||
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(prog="gen-openapi")
|
||||
parser.add_argument(
|
||||
"--app", help='App import string. Eg. "clan_cli.webui.app:app"', default="clan_cli.webui.app:app"
|
||||
)
|
||||
parser.add_argument("--app-dir", help="Directory containing the app", default=".")
|
||||
parser.add_argument(
|
||||
"--out", help="Output file ending in .json", default="tests", type=Path
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.app_dir is not None:
|
||||
print(f"adding {args.app_dir} to sys.path")
|
||||
sys.path.insert(0, args.app_dir)
|
||||
|
||||
print(f"importing app from {args.app}")
|
||||
app = import_from_string(args.app)
|
||||
openapi = app.openapi()
|
||||
version = openapi.get("openapi", "unknown version")
|
||||
|
||||
print(f"writing openapi spec v{version}")
|
||||
with tempfile.TemporaryDirectory() as tmpdirname:
|
||||
|
||||
tmp_dir = Path(tmpdirname)
|
||||
openapi_p = tmp_dir / "openapi.json"
|
||||
openapi_p.write_text(json.dumps(openapi, indent=2))
|
||||
|
||||
gen_code = tmp_dir / "gen_code"
|
||||
|
||||
print(f"generating python client to {args.out}")
|
||||
if not args.out.is_dir():
|
||||
raise Exception(f"{args.out} is not a directory")
|
||||
args.out.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
cmd = [
|
||||
"openapi-generator-cli",
|
||||
"generate",
|
||||
"-g",
|
||||
"python",
|
||||
"-o",
|
||||
f"{gen_code}",
|
||||
"-i",
|
||||
f"{openapi_p}",
|
||||
"--additional-properties=generateSourceCodeOnly=true"
|
||||
]
|
||||
subprocess.run(cmd, check=True, text=True)
|
||||
|
||||
|
||||
src_client: Path = gen_code / "openapi_client"
|
||||
pattern = r"from typing import Any, List, Optional"
|
||||
replacement = "from typing import Any, List, Optional, Dict"
|
||||
replace_in_directory(directory_path=src_client, pattern=pattern, replacement=replacement)
|
||||
|
||||
src_clients_tests = src_client / "test"
|
||||
shutil.rmtree(src_clients_tests)
|
||||
dst_client: Path = args.out / "openapi_client"
|
||||
shutil.rmtree(dst_client, ignore_errors=True)
|
||||
shutil.copytree(src_client, dst_client)
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
16
pkgs/clan-cli/build_docker.sh
Executable file
16
pkgs/clan-cli/build_docker.sh
Executable file
@@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PROJECT_DIR=$(git rev-parse --show-toplevel)
|
||||
"$PROJECT_DIR"/pkgs/clan-cli/upload_ui_assets.sh
|
||||
|
||||
nix build .#clan-docker
|
||||
|
||||
cat <<EOF
|
||||
==============================
|
||||
Please commit the changes to ui-assets.nix and push them to the repository.
|
||||
If you want clan webui to use the new ui assets.
|
||||
$ git commit -m "Update ui-assets.nix" "$PROJECT_DIR/pkgs/ui/nix/ui-assets.nix"
|
||||
$ git push
|
||||
EOF
|
||||
Binary file not shown.
37
pkgs/clan-cli/clan_cli/README.md
Normal file
37
pkgs/clan-cli/clan_cli/README.md
Normal file
@@ -0,0 +1,37 @@
|
||||
**init\_**.py:
|
||||
|
||||
```bash
|
||||
usage: clan webui [-h] [--port PORT] [--host HOST] [--populate] [--emulate] [--no-open] [--dev]
|
||||
[--dev-port DEV_PORT] [--dev-host DEV_HOST] [--reload]
|
||||
[--log-level {critical,error,warning,info,debug,trace}]
|
||||
[sub_url]
|
||||
|
||||
positional arguments:
|
||||
sub_url Sub URL to open in the browser
|
||||
|
||||
options:
|
||||
-h, --help show this help message and exit
|
||||
--port PORT Port to listen on
|
||||
--host HOST Host to listen on
|
||||
--populate Populate the database with dummy data
|
||||
--emulate Emulate two entities c1 and c2 + dlg and ap
|
||||
--no-open Don't open the browser
|
||||
--dev Run in development mode
|
||||
--dev-port DEV_PORT Port to listen on for the dev server
|
||||
--dev-host DEV_HOST Host to listen on
|
||||
--reload Don't reload on changes
|
||||
--log-level {critical,error,warning,info,debug,trace}
|
||||
Log level
|
||||
```
|
||||
|
||||
In this folder are some basic files:
|
||||
|
||||
- config.py
|
||||
- to configer basic value for the server and the emulation
|
||||
- ip/host
|
||||
- ports
|
||||
- emuplate_fast.py
|
||||
- some api call that emulate the behavoir
|
||||
- extra servers with api calls are emulated here
|
||||
|
||||
In the subfolder <webui> is the backend impplemented.
|
||||
@@ -1,14 +1,18 @@
|
||||
# Imports
|
||||
import argparse
|
||||
import logging
|
||||
import sys
|
||||
from types import ModuleType
|
||||
from typing import Optional
|
||||
|
||||
# Custom imports
|
||||
from . import webui
|
||||
from .custom_logger import register
|
||||
from .custom_logger import setup_logging
|
||||
|
||||
# Setting up the logger
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Trying to import argcomplete module, if not present, set it to None
|
||||
argcomplete: Optional[ModuleType] = None
|
||||
try:
|
||||
import argcomplete # type: ignore[no-redef]
|
||||
@@ -16,42 +20,59 @@ except ImportError:
|
||||
pass
|
||||
|
||||
|
||||
# Function to create the main argument parser
|
||||
def create_parser(prog: Optional[str] = None) -> argparse.ArgumentParser:
|
||||
# Creating the main argument parser with a description
|
||||
parser = argparse.ArgumentParser(prog=prog, description="cLAN tool")
|
||||
|
||||
# Adding a debug argument to enable debug logging
|
||||
parser.add_argument(
|
||||
"--debug",
|
||||
help="Enable debug logging",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
# Adding subparsers for different commands
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# Adding a subparser for the "webui" command
|
||||
parser_webui = subparsers.add_parser("webui", help="start webui")
|
||||
# Registering additional arguments for the "webui" command
|
||||
webui.register_parser(parser_webui)
|
||||
|
||||
# if args.debug:
|
||||
register(logging.DEBUG)
|
||||
log.debug("Debug log activated")
|
||||
|
||||
# Using argcomplete for shell autocompletion if available
|
||||
if argcomplete:
|
||||
argcomplete.autocomplete(parser)
|
||||
|
||||
# If no command-line arguments provided, print the help message
|
||||
if len(sys.argv) == 1:
|
||||
parser.print_help()
|
||||
return parser
|
||||
|
||||
|
||||
# this will be the entrypoint under /bin/clan (see pyproject.toml config)
|
||||
### Main entry point function
|
||||
def main() -> None:
|
||||
# Creating the main argument parser
|
||||
parser = create_parser()
|
||||
# Parsing command-line arguments
|
||||
args = parser.parse_args()
|
||||
|
||||
# Setting up logging based on the debug flag
|
||||
if args.debug:
|
||||
setup_logging(logging.DEBUG)
|
||||
log.debug("Debug log activated")
|
||||
else:
|
||||
setup_logging(logging.INFO)
|
||||
|
||||
# If the parsed arguments do not have the "func" attribute, exit
|
||||
if not hasattr(args, "func"):
|
||||
return
|
||||
|
||||
# Calling the function associated with the specified command
|
||||
args.func(args)
|
||||
|
||||
|
||||
# Entry point for script execution
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
88
pkgs/clan-cli/clan_cli/config.py
Normal file
88
pkgs/clan-cli/clan_cli/config.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# CORS configuration
|
||||
cors_url = [
|
||||
"http://localhost",
|
||||
"http://127.0.0.1",
|
||||
"http://0.0.0.0",
|
||||
"http://[::]",
|
||||
]
|
||||
cors_ports = ["*", 3000, 2979, 8001, 8002]
|
||||
cors_whitelist = []
|
||||
for u in cors_url:
|
||||
for p in cors_ports:
|
||||
cors_whitelist.append(f"{u}:{p}")
|
||||
|
||||
# host for the server, frontend, backend and emulators
|
||||
host = "127.0.0.1"
|
||||
|
||||
# Used for eventmessage number to name mapping
|
||||
group_type_to_label = {
|
||||
1: {
|
||||
"name": "Attachement",
|
||||
1: "Request Send",
|
||||
2: "Request Received",
|
||||
3: "Response Send",
|
||||
4: "Response Received",
|
||||
},
|
||||
2: {
|
||||
"name": "Connection Setup",
|
||||
1: "Request Send",
|
||||
2: "Request Received",
|
||||
3: "Response Send",
|
||||
4: "Response Received",
|
||||
},
|
||||
3: {
|
||||
"name": "Presentation",
|
||||
1: "Request Send",
|
||||
2: "Request Received",
|
||||
3: "Respone Send",
|
||||
4: "Respone Received",
|
||||
5: "Respone Ack",
|
||||
},
|
||||
4: {
|
||||
"name": "DID Resolution",
|
||||
1: "Request Send",
|
||||
2: "Request Received",
|
||||
3: "Response Send",
|
||||
4: "Response Received",
|
||||
},
|
||||
5: {
|
||||
"name": "Service De-registration",
|
||||
1: "Send",
|
||||
2: "Received",
|
||||
3: "Success Send",
|
||||
4: "Success Received",
|
||||
},
|
||||
6: {
|
||||
"name": "Service Registration",
|
||||
1: "Send",
|
||||
2: "Received",
|
||||
3: "Success Send",
|
||||
4: "Success Received",
|
||||
},
|
||||
7: {
|
||||
"name": "Service Discovery",
|
||||
1: "Discovery Send",
|
||||
2: "Discovery Received",
|
||||
3: "Result Send",
|
||||
4: "Result Received",
|
||||
},
|
||||
8: {
|
||||
"name": "Service Operation",
|
||||
1: "Request Send",
|
||||
2: "Request Received",
|
||||
3: "Response Send",
|
||||
4: "Response Received",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
# Used for emulation and population for testing
|
||||
port_dlg = 7000
|
||||
port_ap = 7500
|
||||
_port_client_base = 8000
|
||||
c1_port = _port_client_base + 1
|
||||
c2_port = _port_client_base + 2
|
||||
dlg_url = f"http://{host}:{port_dlg}/docs"
|
||||
ap_url = f"http://{host}:{port_ap}/docs"
|
||||
c1_url = f"http://{host}:{c1_port}/docs"
|
||||
c2_url = f"http://{host}:{c2_port}/docs"
|
||||
@@ -61,10 +61,19 @@ def get_caller() -> str:
|
||||
return ret
|
||||
|
||||
|
||||
def register(level: Any) -> None:
|
||||
handler = logging.StreamHandler()
|
||||
handler.setLevel(level)
|
||||
handler.setFormatter(CustomFormatter())
|
||||
logger = logging.getLogger("registerHandler")
|
||||
logger.addHandler(handler)
|
||||
# logging.basicConfig(level=level, handlers=[handler])
|
||||
def setup_logging(level: Any) -> None:
|
||||
# Get the root logger and set its level
|
||||
main_logger = logging.getLogger("clan_cli")
|
||||
main_logger.setLevel(level)
|
||||
|
||||
# Create and add the default handler
|
||||
default_handler = logging.StreamHandler()
|
||||
|
||||
# Create and add your custom handler
|
||||
default_handler.setLevel(level)
|
||||
default_handler.setFormatter(CustomFormatter())
|
||||
main_logger.addHandler(default_handler)
|
||||
|
||||
# Set logging level for other modules used by this module
|
||||
logging.getLogger("asyncio").setLevel(logging.INFO)
|
||||
logging.getLogger("httpx").setLevel(level=logging.WARNING)
|
||||
|
||||
@@ -4,8 +4,8 @@ import sys
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from .clan_types import FlakeName
|
||||
from .errors import ClanError
|
||||
from .types import FlakeName
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
265
pkgs/clan-cli/clan_cli/emulate_fastapi.py
Normal file
265
pkgs/clan-cli/clan_cli/emulate_fastapi.py
Normal file
@@ -0,0 +1,265 @@
|
||||
# Importing necessary modules and packages
|
||||
import sys
|
||||
import time
|
||||
import urllib
|
||||
from datetime import datetime
|
||||
|
||||
# Importing FastAPI and related components
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import HTMLResponse, JSONResponse
|
||||
|
||||
# Importing configuration and schemas from the clan_cli package
|
||||
import clan_cli.config as config
|
||||
from clan_cli.webui.schemas import Resolution
|
||||
|
||||
# Creating FastAPI instances for different applications
|
||||
app_dlg = FastAPI(swagger_ui_parameters={"tryItOutEnabled": True})
|
||||
app_ap = FastAPI(swagger_ui_parameters={"tryItOutEnabled": True})
|
||||
app_c1 = FastAPI(swagger_ui_parameters={"tryItOutEnabled": True})
|
||||
app_c2 = FastAPI(swagger_ui_parameters={"tryItOutEnabled": True})
|
||||
|
||||
# List of FastAPI instances and their associated ports
|
||||
apps = [
|
||||
(app_dlg, config.port_dlg),
|
||||
(app_ap, config.port_ap),
|
||||
(app_c1, config.c1_port),
|
||||
(app_c2, config.c2_port),
|
||||
]
|
||||
for app, port in apps:
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=config.cors_whitelist,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
|
||||
# Healthcheck endpoints for different applications
|
||||
@app_c1.get("/")
|
||||
async def root_c1() -> str:
|
||||
return "C1 is alive"
|
||||
|
||||
|
||||
@app_c1.get("/health")
|
||||
async def healthcheck_c1() -> str:
|
||||
return "200 OK"
|
||||
|
||||
|
||||
@app_c2.get("/")
|
||||
async def root_c2() -> str:
|
||||
return "C2 is alive"
|
||||
|
||||
|
||||
@app_c2.get("/health")
|
||||
async def healthcheck_c2() -> str:
|
||||
return "200 OK"
|
||||
|
||||
|
||||
@app_dlg.get("/")
|
||||
async def root_dlg() -> str:
|
||||
return "DLG is alive"
|
||||
|
||||
|
||||
@app_dlg.get("/health")
|
||||
async def healthcheck_dlg() -> str:
|
||||
return "200 OK"
|
||||
|
||||
|
||||
@app_ap.get("/")
|
||||
async def root_ap() -> str:
|
||||
return "AP is alive"
|
||||
|
||||
|
||||
@app_ap.get("/health")
|
||||
async def healthcheck_ap() -> str:
|
||||
return "200 OK"
|
||||
|
||||
|
||||
# Function for performing health checks on a given URL with retries
|
||||
def get_health(*, url: str, max_retries: int = 20, delay: float = 0.2) -> str | None:
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
with urllib.request.urlopen(url) as response: # type: ignore
|
||||
return response.read()
|
||||
except urllib.error.URLError as e: # type: ignore
|
||||
print(f"Attempt {attempt + 1} failed: {e.reason}", file=sys.stderr)
|
||||
time.sleep(delay)
|
||||
return None
|
||||
|
||||
|
||||
# Service consumption emulation for c1 which returns a gif1
|
||||
@app_c1.get("/v1/print_daemon1", response_class=HTMLResponse)
|
||||
async def consume_service_from_other_entity_c1() -> HTMLResponse:
|
||||
# HTML content for the response
|
||||
html_content = """
|
||||
<html>
|
||||
<body>
|
||||
<div style="width:480px"><iframe allow="fullscreen" frameBorder="0" height="270" src="https://giphy.com/embed/IOWD3uknMxYyh7CsgN/video" width="480"></iframe></div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
time.sleep(3)
|
||||
return HTMLResponse(content=html_content, status_code=200)
|
||||
|
||||
|
||||
@app_c1.get("/v1/print_daemon1/register", response_class=JSONResponse)
|
||||
async def register_c1() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "registered"}, status_code=200)
|
||||
|
||||
|
||||
@app_c1.get("/v1/print_daemon1/deregister", response_class=JSONResponse)
|
||||
async def deregister_c1() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "deregistered"}, status_code=200)
|
||||
|
||||
|
||||
@app_c2.get("/v1/print_daemon2", response_class=HTMLResponse)
|
||||
async def consume_service_from_other_entity_c2() -> HTMLResponse:
|
||||
# Similar HTML content for the response
|
||||
html_content = """
|
||||
<html>
|
||||
<body>
|
||||
<div style="width:480px"><iframe allow="fullscreen" frameBorder="0" height="270" src="https://giphy.com/embed/IOWD3uknMxYyh7CsgN/video" width="480"></iframe></div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
time.sleep(3)
|
||||
return HTMLResponse(content=html_content, status_code=200)
|
||||
|
||||
|
||||
@app_c2.get("/v1/print_daemon2/register", response_class=JSONResponse)
|
||||
async def register_c2() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "registered"}, status_code=200)
|
||||
|
||||
|
||||
@app_c2.get("/v1/print_daemon2/deregister", response_class=JSONResponse)
|
||||
async def deregister_c2() -> JSONResponse:
|
||||
time.sleep(2)
|
||||
return JSONResponse(content={"status": "deregistered"}, status_code=200)
|
||||
|
||||
|
||||
@app_ap.get("/ap_list_of_services", response_class=JSONResponse)
|
||||
async def ap_list_of_services() -> JSONResponse:
|
||||
# Sample list of services as a JSON response
|
||||
res = [
|
||||
# Service 1
|
||||
{
|
||||
"uuid": "bdd640fb-0667-1ad1-1c80-317fa3b1799d",
|
||||
"service_name": "Carlos Printing0",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8001/v1/print_daemon1",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:120",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
{
|
||||
"name": "register",
|
||||
"endpoint": "http://127.0.0.1:8001/v1/print_daemon1/register",
|
||||
},
|
||||
{
|
||||
"name": "deregister",
|
||||
"endpoint": "http://127.0.0.1:8001/v1/print_daemon1/deregister",
|
||||
},
|
||||
]
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
# Service 2 (similar structure)
|
||||
{
|
||||
"uuid": "23b8c1e9-3924-56de-3eb1-3b9046685257",
|
||||
"service_name": "Carlos Printing1",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8002/v1/print_daemon2",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:121",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
{
|
||||
"name": "register",
|
||||
"endpoint": "http://127.0.0.1:8002/v1/print_daemon2/register",
|
||||
},
|
||||
{
|
||||
"name": "deregister",
|
||||
"endpoint": "http://127.0.0.1:8002/v1/print_daemon2/deregister",
|
||||
},
|
||||
]
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
{
|
||||
"uuid": "bd9c66b3-ad3c-2d6d-1a3d-1fa7bc8960a9",
|
||||
"service_name": "Carlos Printing2",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8003/v1/print_daemon3",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:122",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
{
|
||||
"name": "register",
|
||||
"endpoint": "http://127.0.0.1:8003/v1/print_daemon3/register",
|
||||
},
|
||||
{
|
||||
"name": "deregister",
|
||||
"endpoint": "http://127.0.0.1:8003/v1/print_daemon3/deregister",
|
||||
},
|
||||
]
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
{
|
||||
"uuid": "972a8469-1641-9f82-8b9d-2434e465e150",
|
||||
"service_name": "Carlos Printing3",
|
||||
"service_type": "3D Printing",
|
||||
"endpoint_url": "http://127.0.0.1:8004/v1/print_daemon4",
|
||||
"other": {},
|
||||
"entity_did": "did:sov:test:123",
|
||||
"status": {"data": ["draft", "registered"]},
|
||||
"action": {
|
||||
"data": [
|
||||
{
|
||||
"name": "register",
|
||||
"endpoint": "http://127.0.0.1:8004/v1/print_daemon4/register",
|
||||
},
|
||||
{
|
||||
"name": "deregister",
|
||||
"endpoint": "http://127.0.0.1:8004/v1/print_daemon4/deregister",
|
||||
},
|
||||
]
|
||||
},
|
||||
"usage": [{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
},
|
||||
]
|
||||
return JSONResponse(content=res, status_code=200)
|
||||
|
||||
|
||||
@app_dlg.get("/dlg_list_of_did_resolutions", response_model=list[Resolution])
|
||||
async def dlg_list_of_did_resolutions() -> list[Resolution]:
|
||||
res = []
|
||||
|
||||
res.append(
|
||||
Resolution(
|
||||
timestamp=datetime.fromisoformat("2021-10-12T12:52:00.000Z"),
|
||||
requester_name="C1",
|
||||
requester_did="did:sov:test:1122",
|
||||
resolved_did="did:sov:test:1234",
|
||||
other={"test": "test"},
|
||||
)
|
||||
)
|
||||
res.append(
|
||||
Resolution(
|
||||
timestamp=datetime.fromisoformat("2021-10-12T12:53:00.000Z"),
|
||||
requester_name="C2",
|
||||
requester_did="did:sov:test:1123",
|
||||
resolved_did="did:sov:test:1234",
|
||||
other={"test": "test"},
|
||||
)
|
||||
)
|
||||
return res
|
||||
6
pkgs/clan-cli/clan_cli/webui/README.md
Normal file
6
pkgs/clan-cli/clan_cli/webui/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
Here are the files found for the backend of the service.
|
||||
|
||||
- the backed is using a sql light db with sqlachremy
|
||||
- this is done in
|
||||
- sql\_\*.py, schema.py, tags.py
|
||||
- subfolder: routers which also contains the apicall defenitions
|
||||
@@ -1,27 +1,73 @@
|
||||
import argparse
|
||||
import logging
|
||||
from typing import Callable, NoReturn, Optional
|
||||
|
||||
# Get the logger for this module
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Initialize variables for server startup and potential ImportError
|
||||
start_server: Optional[Callable] = None
|
||||
ServerImportError: Optional[ImportError] = None
|
||||
|
||||
# Try importing the start_server function from the server module
|
||||
try:
|
||||
from .server import start_server
|
||||
except ImportError as e:
|
||||
# If ImportError occurs, log the exception and store it in ServerImportError
|
||||
log.exception(e)
|
||||
ServerImportError = e
|
||||
|
||||
|
||||
# Function to be called when FastAPI is not installed
|
||||
##########################################################################################
|
||||
# usage: clan webui [-h] [--port PORT] [--host HOST] [--populate] [--emulate] [--no-open] [--dev]
|
||||
# [--dev-port DEV_PORT] [--dev-host DEV_HOST] [--reload]
|
||||
# [--log-level {critical,error,warning,info,debug,trace}]
|
||||
# [sub_url]
|
||||
#
|
||||
# positional arguments:
|
||||
# sub_url Sub URL to open in the browser
|
||||
#
|
||||
# options:
|
||||
# -h, --help show this help message and exit
|
||||
# --port PORT Port to listen on
|
||||
# --host HOST Host to listen on
|
||||
# --populate Populate the database with dummy data
|
||||
# --emulate Emulate two entities c1 and c2 + dlg and ap
|
||||
# --no-open Don't open the browser
|
||||
# --dev Run in development mode
|
||||
# --dev-port DEV_PORT Port to listen on for the dev server
|
||||
# --dev-host DEV_HOST Host to listen on
|
||||
# --reload Don't reload on changes
|
||||
# --log-level {critical,error,warning,info,debug,trace}
|
||||
# Log level
|
||||
##########################################################################################
|
||||
def fastapi_is_not_installed(_: argparse.Namespace) -> NoReturn:
|
||||
assert ServerImportError is not None
|
||||
print(
|
||||
f"Dependencies for the webserver is not installed. The webui command has been disabled ({ServerImportError})"
|
||||
f"Dependencies for the webserver are not installed. The webui command has been disabled ({ServerImportError})"
|
||||
)
|
||||
exit(1)
|
||||
|
||||
|
||||
# Function to register command-line arguments for the webserver
|
||||
def register_parser(parser: argparse.ArgumentParser) -> None:
|
||||
parser.add_argument("--port", type=int, default=2979, help="Port to listen on")
|
||||
parser.add_argument(
|
||||
"--host", type=str, default="localhost", help="Host to listen on"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--populate",
|
||||
action="store_true",
|
||||
help="Populate the database with dummy data",
|
||||
default=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--emulate",
|
||||
action="store_true",
|
||||
help="Emulate two entities c1 and c2 + dlg and ap",
|
||||
default=False,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--no-open", action="store_true", help="Don't open the browser", default=False
|
||||
)
|
||||
@@ -53,10 +99,10 @@ def register_parser(parser: argparse.ArgumentParser) -> None:
|
||||
type=str,
|
||||
default="/",
|
||||
nargs="?",
|
||||
help="Sub url to open in the browser",
|
||||
help="Sub URL to open in the browser",
|
||||
)
|
||||
|
||||
# Set the args.func variable in args
|
||||
# Set the args.func variable in args based on whether FastAPI is installed
|
||||
if start_server is None:
|
||||
parser.set_defaults(func=fastapi_is_not_installed)
|
||||
else:
|
||||
|
||||
@@ -5,8 +5,8 @@ from typing import Any
|
||||
from pydantic import AnyUrl, BaseModel, validator
|
||||
from pydantic.tools import parse_obj_as
|
||||
|
||||
from ..clan_types import validate_path
|
||||
from ..dirs import clan_data_dir, clan_flakes_dir
|
||||
from ..types import validate_path
|
||||
|
||||
DEFAULT_URL = parse_obj_as(AnyUrl, "http://localhost:8000")
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from enum import Enum
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class Status(Enum):
|
||||
@@ -12,3 +12,43 @@ class Status(Enum):
|
||||
class Machine(BaseModel):
|
||||
name: str
|
||||
status: Status
|
||||
|
||||
|
||||
class RepositoryBase(BaseModel):
|
||||
title: str
|
||||
description: str | None = None
|
||||
|
||||
|
||||
class RepositoryCreate(RepositoryBase):
|
||||
pass
|
||||
|
||||
|
||||
class Repository(RepositoryBase):
|
||||
id: int
|
||||
prod_id: str
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class ProducerBase(BaseModel):
|
||||
id: int
|
||||
|
||||
|
||||
class ProducerCreate(ProducerBase):
|
||||
jsonblob: int = Field(
|
||||
42,
|
||||
title="The Json",
|
||||
description="this is the value of json",
|
||||
gt=30,
|
||||
lt=50,
|
||||
list=[1, 2, "3"],
|
||||
)
|
||||
|
||||
|
||||
class Producer(ProducerBase):
|
||||
id: int
|
||||
repos: list[Repository] = []
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
@@ -1,49 +1,83 @@
|
||||
# Imports
|
||||
import logging
|
||||
|
||||
# Import FastAPI components and SQLAlchemy related modules
|
||||
from fastapi import FastAPI
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.routing import APIRoute
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
# Import configs
|
||||
from ..config import cors_ports, cors_url
|
||||
|
||||
# Import custom modules and classes
|
||||
from ..errors import ClanError
|
||||
from . import sql_models
|
||||
from .assets import asset_path
|
||||
from .error_handlers import clan_error_handler
|
||||
from .routers import health, root
|
||||
from .error_handlers import clan_error_handler, sql_error_handler
|
||||
from .routers import endpoints, health, root
|
||||
from .sql_db import engine
|
||||
from .tags import tags_metadata
|
||||
|
||||
cors_whitelist = []
|
||||
for u in cors_url:
|
||||
for p in cors_ports:
|
||||
cors_whitelist.append(f"{u}:{p}")
|
||||
|
||||
origins = [
|
||||
"http://localhost:3000",
|
||||
]
|
||||
# Logging setup
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Function to set up and configure the FastAPI application
|
||||
def setup_app() -> FastAPI:
|
||||
app = FastAPI()
|
||||
# Uncomment the following line to drop existing tables during startup (if needed)
|
||||
# sql_models.Base.metadata.drop_all(engine)
|
||||
|
||||
# Create tables in the database using SQLAlchemy
|
||||
sql_models.Base.metadata.create_all(bind=engine)
|
||||
|
||||
# Initialize FastAPI application with lifespan management
|
||||
app = FastAPI(swagger_ui_parameters={"tryItOutEnabled": True})
|
||||
|
||||
# Configure CORS middleware
|
||||
app.add_middleware(
|
||||
CORSMiddleware,
|
||||
allow_origins=origins,
|
||||
allow_origins=cors_whitelist,
|
||||
allow_credentials=True,
|
||||
allow_methods=["*"],
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Include routers for various endpoints and components
|
||||
app.include_router(health.router)
|
||||
app.include_router(endpoints.router)
|
||||
|
||||
# Needs to be last in register. Because of wildcard route
|
||||
# Needs to be last in registration due to wildcard route
|
||||
app.include_router(root.router)
|
||||
app.add_exception_handler(ClanError, clan_error_handler)
|
||||
|
||||
# Add custom exception handlers
|
||||
app.add_exception_handler(ClanError, clan_error_handler) # type: ignore
|
||||
app.add_exception_handler(SQLAlchemyError, sql_error_handler) # type: ignore
|
||||
|
||||
# Mount the "static" route for serving static files
|
||||
app.mount("/static", StaticFiles(directory=asset_path()), name="static")
|
||||
|
||||
# Add tag descriptions to the OpenAPI schema
|
||||
app.openapi_tags = tags_metadata
|
||||
|
||||
# Assign operation IDs to API routes
|
||||
for route in app.routes:
|
||||
if isinstance(route, APIRoute):
|
||||
route.operation_id = route.name # in this case, 'read_items'
|
||||
log.debug(f"Registered route: {route}")
|
||||
|
||||
# Log registered exception handlers
|
||||
for i in app.exception_handlers.items():
|
||||
log.debug(f"Registered exception handler: {i}")
|
||||
|
||||
return app
|
||||
|
||||
|
||||
# Create an instance of the FastAPI application
|
||||
app = setup_app()
|
||||
|
||||
13
pkgs/clan-cli/clan_cli/webui/db_types.py
Normal file
13
pkgs/clan-cli/clan_cli/webui/db_types.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class Status(Enum):
|
||||
ONLINE = "online"
|
||||
OFFLINE = "offline"
|
||||
UNKNOWN = "unknown"
|
||||
|
||||
|
||||
class Role(Enum):
|
||||
PROSUMER = "service_prosumer"
|
||||
AP = "AP"
|
||||
DLG = "DLG"
|
||||
@@ -3,14 +3,29 @@ import logging
|
||||
from fastapi import Request, status
|
||||
from fastapi.encoders import jsonable_encoder
|
||||
from fastapi.responses import JSONResponse
|
||||
from sqlalchemy.exc import SQLAlchemyError
|
||||
|
||||
from ..errors import ClanError
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def sql_error_handler(request: Request, exc: SQLAlchemyError) -> JSONResponse:
|
||||
log.exception(exc)
|
||||
detail = [
|
||||
{
|
||||
"loc": [],
|
||||
"msg": exc._message(),
|
||||
}
|
||||
]
|
||||
return JSONResponse(
|
||||
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
|
||||
content=jsonable_encoder(dict(detail=detail)),
|
||||
)
|
||||
|
||||
|
||||
def clan_error_handler(request: Request, exc: ClanError) -> JSONResponse:
|
||||
log.error("ClanError: %s", exc)
|
||||
log.exception(exc)
|
||||
detail = [
|
||||
{
|
||||
"loc": [],
|
||||
|
||||
1
pkgs/clan-cli/clan_cli/webui/routers/README.md
Normal file
1
pkgs/clan-cli/clan_cli/webui/routers/README.md
Normal file
@@ -0,0 +1 @@
|
||||
In the <endpoints.py> are the api endpoints implemented which could be used of the user/s.
|
||||
463
pkgs/clan-cli/clan_cli/webui/routers/endpoints.py
Normal file
463
pkgs/clan-cli/clan_cli/webui/routers/endpoints.py
Normal file
@@ -0,0 +1,463 @@
|
||||
import json
|
||||
import logging
|
||||
import time
|
||||
import typing
|
||||
from collections import OrderedDict
|
||||
from typing import Any, List, Optional
|
||||
|
||||
import httpx
|
||||
from fastapi import APIRouter, BackgroundTasks, Depends, Query
|
||||
from fastapi.responses import HTMLResponse, PlainTextResponse
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from clan_cli.config import ap_url, c1_url, c2_url, dlg_url, group_type_to_label
|
||||
|
||||
from ...errors import ClanError
|
||||
from .. import sql_crud, sql_db, sql_models
|
||||
from ..schemas import (
|
||||
Entity,
|
||||
EntityCreate,
|
||||
Eventmessage,
|
||||
EventmessageCreate,
|
||||
Resolution,
|
||||
Role,
|
||||
Service,
|
||||
ServiceCreate,
|
||||
ServiceUsageCreate,
|
||||
)
|
||||
from ..tags import Tags
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# API Endpoints for all tables
|
||||
# see the default api documentation under:
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/DefaultApi.md
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Service #
|
||||
# #
|
||||
#########################
|
||||
# see the corresponding documentation under:
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/Service.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/ServiceCreate.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/ServiceUsageCreate.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/ServicesApi.md
|
||||
@router.post("/api/v1/service", response_model=Service, tags=[Tags.services])
|
||||
def create_service(
|
||||
service: ServiceCreate, db: Session = Depends(sql_db.get_db)
|
||||
) -> Service:
|
||||
services = sql_crud.create_service(db=db, service=service)
|
||||
return services
|
||||
|
||||
|
||||
@router.post("/api/v1/service_usage", response_model=Service, tags=[Tags.services])
|
||||
def add_service_usage(
|
||||
usage: ServiceUsageCreate,
|
||||
service_uuid: str = "bdd640fb-0667-1ad1-1c80-317fa3b1799d",
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> Service:
|
||||
service = sql_crud.add_service_usage(db, service_uuid, usage)
|
||||
return service
|
||||
|
||||
|
||||
@router.put("/api/v1/inc_service_usage", response_model=Service, tags=[Tags.services])
|
||||
def inc_service_usage(
|
||||
usage: ServiceUsageCreate,
|
||||
consumer_entity_did: str = "did:sov:test:120",
|
||||
service_uuid: str = "bdd640fb-0667-1ad1-1c80-317fa3b1799d",
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> Service:
|
||||
service = sql_crud.increment_service_usage(db, service_uuid, consumer_entity_did)
|
||||
return service
|
||||
|
||||
|
||||
@router.put("/api/v1/service", response_model=Service, tags=[Tags.services])
|
||||
def update_service(
|
||||
service: ServiceCreate,
|
||||
uuid: str = "bdd640fb-0667-1ad1-1c80-317fa3b1799d",
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> Service:
|
||||
service = sql_crud.set_service(db, uuid, service)
|
||||
return service
|
||||
|
||||
|
||||
@router.get("/api/v1/services", response_model=List[Service], tags=[Tags.services])
|
||||
def get_all_services(
|
||||
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
|
||||
) -> List[sql_models.Service]:
|
||||
services = sql_crud.get_services(db, skip=skip, limit=limit)
|
||||
return services
|
||||
|
||||
|
||||
@router.get(
|
||||
"/api/v1/service_by_did", response_model=List[Service], tags=[Tags.services]
|
||||
)
|
||||
def get_service_by_did(
|
||||
entity_did: str = "did:sov:test:120",
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> List[sql_models.Service]:
|
||||
service = sql_crud.get_services_by_entity_did(db, entity_did=entity_did)
|
||||
return service
|
||||
|
||||
|
||||
@router.get("/api/v1/service", response_model=Service, tags=[Tags.services])
|
||||
def get_service_by_uuid(
|
||||
uuid: str = "bdd640fb-0667-1ad1-1c80-317fa3b1799d",
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> Optional[sql_models.Service]:
|
||||
service = sql_crud.get_service_by_uuid(db, uuid=uuid)
|
||||
return service
|
||||
|
||||
|
||||
@router.get(
|
||||
"/api/v1/services_without_entity",
|
||||
response_model=List[Service],
|
||||
tags=[Tags.services],
|
||||
)
|
||||
def get_services_without_entity(
|
||||
entity_did: str = "did:sov:test:120",
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> List[sql_models.Service]:
|
||||
service = sql_crud.get_services_without_entity_id(db, entity_did=entity_did)
|
||||
return service
|
||||
|
||||
|
||||
@router.delete("/api/v1/service", tags=[Tags.services])
|
||||
def delete_service(
|
||||
entity_did: str = "did:sov:test:120",
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> dict[str, str]:
|
||||
sql_crud.delete_service_by_entity_did(db, entity_did)
|
||||
return {"message": "service deleted"}
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Entity #
|
||||
# #
|
||||
#########################
|
||||
# see the corresponding documentation under:
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/Entity.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/EntityCreate.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/EntitiesApi.md
|
||||
@router.post("/api/v1/entity", response_model=Entity, tags=[Tags.entities])
|
||||
def create_entity(
|
||||
entity: EntityCreate, db: Session = Depends(sql_db.get_db)
|
||||
) -> sql_models.Entity:
|
||||
return sql_crud.create_entity(db, entity)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/api/v1/entity_by_roles", response_model=List[Entity], tags=[Tags.entities]
|
||||
)
|
||||
def get_entity_by_roles(
|
||||
roles: List[Role] = Query(...), db: Session = Depends(sql_db.get_db)
|
||||
) -> List[sql_models.Entity]:
|
||||
entity = sql_crud.get_entity_by_role(db, roles=roles)
|
||||
return entity
|
||||
|
||||
|
||||
@router.get("/api/v1/entity_by_role", response_model=List[Entity], tags=[Tags.entities])
|
||||
def get_entity_by_role(
|
||||
role: Role, db: Session = Depends(sql_db.get_db)
|
||||
) -> List[sql_models.Entity]:
|
||||
entity = sql_crud.get_entity_by_role(db, roles=[role])
|
||||
return entity
|
||||
|
||||
|
||||
@router.get("/api/v1/entities", response_model=List[Entity], tags=[Tags.entities])
|
||||
def get_all_entities(
|
||||
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
|
||||
) -> List[sql_models.Entity]:
|
||||
entities = sql_crud.get_entities(db, skip=skip, limit=limit)
|
||||
return entities
|
||||
|
||||
|
||||
@router.get("/api/v1/entity", response_model=Entity, tags=[Tags.entities])
|
||||
def get_entity_by_did(
|
||||
entity_did: str = "did:sov:test:120",
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> Optional[sql_models.Entity]:
|
||||
entity = sql_crud.get_entity_by_name_or_did(db, name=entity_did)
|
||||
return entity
|
||||
|
||||
|
||||
@router.get(
|
||||
"/api/v1/attached_entities",
|
||||
response_model=List[Entity],
|
||||
tags=[Tags.entities],
|
||||
)
|
||||
def get_attached_entities(
|
||||
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
|
||||
) -> List[sql_models.Entity]:
|
||||
entities = sql_crud.get_attached_entities(db, skip=skip, limit=limit)
|
||||
return entities
|
||||
|
||||
|
||||
@router.put("/api/v1/detach", tags=[Tags.entities])
|
||||
def detach_entity(
|
||||
background_tasks: BackgroundTasks,
|
||||
entity_did: str = "did:sov:test:120",
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> dict[str, str]:
|
||||
sql_crud.set_stop_health_task(db, entity_did, True)
|
||||
return {"message": f"Detached {entity_did} successfully"}
|
||||
|
||||
|
||||
@router.put("/api/v1/attach", tags=[Tags.entities])
|
||||
def attach_entity(
|
||||
background_tasks: BackgroundTasks,
|
||||
entity_did: str = "did:sov:test:120",
|
||||
skip: int = 0,
|
||||
limit: int = 100,
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> dict[str, str]:
|
||||
entity = sql_crud.get_entity_by_did(db, did=entity_did)
|
||||
if entity is None:
|
||||
raise ClanError(f"Entity with did '{entity_did}' not found")
|
||||
url = f"http://{entity.ip}/health"
|
||||
sql_crud.set_stop_health_task(db, entity_did, False)
|
||||
print("Start health query at", url)
|
||||
background_tasks.add_task(attach_entity_loc, db, entity_did)
|
||||
return {"message": f"Started attachment task for {entity.name}"}
|
||||
|
||||
|
||||
@router.get("/api/v1/is_attached", tags=[Tags.entities])
|
||||
def is_attached(
|
||||
entity_did: str = "did:sov:test:120", db: Session = Depends(sql_db.get_db)
|
||||
) -> dict[str, str]:
|
||||
entity = sql_crud.get_entity_by_did(db, did=entity_did)
|
||||
|
||||
if entity is None:
|
||||
raise ClanError(f"Entity with did '{entity_did}' not found")
|
||||
|
||||
timer = 0.0
|
||||
timeout = 2
|
||||
while not entity.attached:
|
||||
time.sleep(0.1)
|
||||
|
||||
timer += 0.1
|
||||
if timer > timeout:
|
||||
url = f"http://{entity.ip}"
|
||||
raise ClanError(f"Entity at {url} not reachable")
|
||||
|
||||
db.refresh(entity)
|
||||
return {"message": f"Attached to {entity.name} successfully"}
|
||||
|
||||
|
||||
def attach_entity_loc(db: Session, entity_did: str) -> None:
|
||||
entity = sql_crud.get_entity_by_did(db, did=entity_did)
|
||||
try:
|
||||
assert entity is not None
|
||||
url = f"http://{entity.ip}/health"
|
||||
|
||||
while entity.stop_health_task is False:
|
||||
response = httpx.get(url, timeout=2)
|
||||
if response.status_code != 200:
|
||||
raise ClanError(
|
||||
f"Entity with did '{entity_did}' returned {response.status_code}"
|
||||
)
|
||||
|
||||
if entity.attached is False:
|
||||
sql_crud.set_attached_by_entity_did(db, entity_did, True)
|
||||
if entity is None:
|
||||
raise ClanError(f"Entity with did '{entity_did}' has been deleted")
|
||||
|
||||
time.sleep(1)
|
||||
db.refresh(entity)
|
||||
except Exception:
|
||||
print(f"Entity {entity_did} not reachable at {url}")
|
||||
finally:
|
||||
sql_crud.set_attached_by_entity_did(db, entity_did, False)
|
||||
sql_crud.set_stop_health_task(db, entity_did, False)
|
||||
|
||||
|
||||
@router.delete("/api/v1/entity", tags=[Tags.entities])
|
||||
def delete_entity(
|
||||
entity_did: str = "did:sov:test:120",
|
||||
db: Session = Depends(sql_db.get_db),
|
||||
) -> dict[str, str]:
|
||||
sql_crud.delete_entity_by_did_recursive(db, did=entity_did)
|
||||
return {"message": "Entity deleted and all relations to that entity"}
|
||||
|
||||
|
||||
def get_rpc_by_role(db: Session, role: Role, path: str) -> Any:
|
||||
matching_entities = sql_crud.get_entity_by_role(db, roles=[role])
|
||||
if matching_entities is None:
|
||||
raise ClanError(f"No {role} found")
|
||||
if len(matching_entities) > 1:
|
||||
raise ClanError(f"More than one {role} found")
|
||||
if len(matching_entities) == 0:
|
||||
raise ClanError(f"No {role} found")
|
||||
dlg = matching_entities[0]
|
||||
|
||||
url = f"http://{dlg.ip}/{path}"
|
||||
try:
|
||||
response = httpx.get(url, timeout=2)
|
||||
except httpx.HTTPError as e:
|
||||
raise ClanError(f"{role} not reachable at {url}") from e
|
||||
|
||||
if response.status_code != 200:
|
||||
raise ClanError(f"{role} returned {response.status_code}")
|
||||
|
||||
return response.json()
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Resolution #
|
||||
# #
|
||||
#########################
|
||||
# see the corresponding documentation under:
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/Resolution.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/ResolutionApi.md
|
||||
@router.get(
|
||||
"/api/v1/resolutions", response_model=List[Resolution], tags=[Tags.resolutions]
|
||||
)
|
||||
def get_all_resolutions(
|
||||
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
|
||||
) -> List[Resolution]:
|
||||
return get_rpc_by_role(db, Role("DLG"), "dlg_list_of_did_resolutions")
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Repository #
|
||||
# #
|
||||
#########################
|
||||
# see the corresponding documentation under:
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/RepositoriesApi.md
|
||||
@router.get(
|
||||
"/api/v1/repositories", tags=[Tags.repositories], response_model=List[Service]
|
||||
)
|
||||
def get_all_repositories(
|
||||
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
|
||||
) -> List[Service]:
|
||||
return get_rpc_by_role(db, Role("AP"), "ap_list_of_services")
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Eventmessage #
|
||||
# #
|
||||
#########################
|
||||
# see the corresponding documentation under:
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/Eventmessage.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/EventmessageCreate.md
|
||||
### pkgs/clan-cli/tests/openapi_client/docs/EventmessageApi.md
|
||||
@router.post(
|
||||
"/api/v1/event_message", response_model=Eventmessage, tags=[Tags.eventmessages]
|
||||
)
|
||||
def create_eventmessage(
|
||||
eventmsg: EventmessageCreate, db: Session = Depends(sql_db.get_db)
|
||||
) -> EventmessageCreate:
|
||||
return sql_crud.create_eventmessage(db, eventmsg)
|
||||
|
||||
|
||||
@typing.no_type_check
|
||||
@router.get(
|
||||
"/api/v1/event_messages",
|
||||
response_class=PlainTextResponse,
|
||||
tags=[Tags.eventmessages],
|
||||
)
|
||||
def get_all_eventmessages(
|
||||
skip: int = 0, limit: int = 100, db: Session = Depends(sql_db.get_db)
|
||||
) -> PlainTextResponse:
|
||||
# SQL sorts eventmessages by timestamp, so we don't need to sort them here
|
||||
eventmessages = sql_crud.get_eventmessages(db, skip=skip, limit=limit)
|
||||
cresult: List[OrderedDict[int, OrderedDict[int, List[Eventmessage]]]] = []
|
||||
|
||||
cresult_idx = 0
|
||||
cresult.append(OrderedDict())
|
||||
for idx, msg in enumerate(eventmessages):
|
||||
# Use the group_type_to_label from config.py to get the group name and msg_type name
|
||||
group = group_type_to_label.get(msg.group, None)
|
||||
group_name = (
|
||||
str(group.get("name", None)) if group is not None else str(msg.group)
|
||||
)
|
||||
msg_type_name = (
|
||||
group.get(msg.msg_type, None) if group is not None else str(msg.msg_type)
|
||||
)
|
||||
|
||||
# Get the name of the src and des entity from the database
|
||||
src_name = sql_crud.get_entity_by_did(db, msg.src_did)
|
||||
src_name = msg.src_did if src_name is None else src_name.name
|
||||
des_name = sql_crud.get_entity_by_did(db, msg.des_did)
|
||||
des_name = msg.des_did if des_name is None else des_name.name
|
||||
|
||||
result = cresult[cresult_idx]
|
||||
|
||||
if result.get("group_name") is None:
|
||||
# Initialize the result array and dictionary
|
||||
result["group_name"] = group_name
|
||||
elif result["group_name"] != group_name:
|
||||
# If the group name changed, create a new result array and dictionary
|
||||
cresult_idx += 1
|
||||
cresult.append(OrderedDict())
|
||||
result = cresult[cresult_idx]
|
||||
result["group_name"] = group_name
|
||||
|
||||
if result.get("groups") is None:
|
||||
result["groups"] = OrderedDict()
|
||||
|
||||
if result["groups"].get(msg.group_id) is None:
|
||||
result["groups"][msg.group_id] = []
|
||||
|
||||
# Append the eventmessage to the result array
|
||||
result_arr = result["groups"][msg.group_id]
|
||||
result_arr.append(
|
||||
Eventmessage(
|
||||
id=msg.id,
|
||||
timestamp=msg.timestamp,
|
||||
group=msg.group,
|
||||
group_name=group_name,
|
||||
group_id=msg.group_id,
|
||||
msg_type=msg.msg_type,
|
||||
msg_type_name=msg_type_name,
|
||||
src_did=msg.src_did,
|
||||
src_name=src_name,
|
||||
des_did=msg.des_did,
|
||||
des_name=des_name,
|
||||
msg=msg.msg,
|
||||
).dict()
|
||||
)
|
||||
|
||||
return PlainTextResponse(content=json.dumps(cresult, indent=4), status_code=200)
|
||||
|
||||
|
||||
##############################
|
||||
# #
|
||||
# EMULATED API ENDPOINTS #
|
||||
# #
|
||||
##############################
|
||||
@router.get("/emulate", response_class=HTMLResponse)
|
||||
def get_emulated_enpoints() -> HTMLResponse:
|
||||
html_content = f"""
|
||||
<html>
|
||||
<head>
|
||||
<title>Emulated API</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Emulated API</h1>
|
||||
<p>Emulated API endpoints for testing purposes.</p>
|
||||
<p>DLG: <a href="{dlg_url}" >{dlg_url} </a></p>
|
||||
<p>AP: <a href="{ap_url}">{ap_url}</a></p>
|
||||
<p>C1: <a href="{c1_url}">{c1_url} </a></p>
|
||||
<p>C2: <a href="{c2_url}">{c2_url}</a></p>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
return HTMLResponse(content=html_content, status_code=200)
|
||||
@@ -1,8 +1,13 @@
|
||||
from fastapi import APIRouter
|
||||
|
||||
from ..schemas import Machine, Status
|
||||
|
||||
router = APIRouter()
|
||||
|
||||
|
||||
@router.get("/health", include_in_schema=False)
|
||||
async def health() -> str:
|
||||
return "OK"
|
||||
@router.get("/health", include_in_schema=True)
|
||||
async def health() -> Machine: # str:
|
||||
return Machine(name="test", status=Status.ONLINE)
|
||||
|
||||
|
||||
# return "OK"
|
||||
|
||||
205
pkgs/clan-cli/clan_cli/webui/routers/messenger.html
Normal file
205
pkgs/clan-cli/clan_cli/webui/routers/messenger.html
Normal file
@@ -0,0 +1,205 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
if (typeof WebSocket != "undefined") {
|
||||
$("#ask").show();
|
||||
} else {
|
||||
$("#error").show();
|
||||
}
|
||||
|
||||
// join on enter
|
||||
$("#ask input").keydown(function (event) {
|
||||
if (event.keyCode == 13) {
|
||||
$("#ask a").click();
|
||||
}
|
||||
});
|
||||
|
||||
// join on click
|
||||
$("#ask a").click(function () {
|
||||
join($("#ask input").val());
|
||||
$("#ask").hide();
|
||||
$("#channel").show();
|
||||
$("input#message").focus();
|
||||
});
|
||||
|
||||
function join(name) {
|
||||
var host = window.location.host.split(":")[0];
|
||||
var ws = new WebSocket("ws://localhost:2979/ws2");
|
||||
|
||||
var container = $("div#msgs");
|
||||
ws.onmessage = function (evt) {
|
||||
var obj = JSON.parse(evt.data);
|
||||
if (typeof obj != "object") return;
|
||||
console.log("Received: " + obj);
|
||||
|
||||
var action = obj["action"];
|
||||
var struct = container.find("li." + action + ":first");
|
||||
if (struct.length < 1) {
|
||||
console.log("Could not handle: " + evt.data);
|
||||
return;
|
||||
}
|
||||
|
||||
var msg = struct.clone();
|
||||
msg.find(".time").text(new Date().toString("HH:mm:ss"));
|
||||
|
||||
if (action == "message") {
|
||||
var matches;
|
||||
if ((matches = obj["message"].match(/^\s*[\/\\]me\s(.*)/))) {
|
||||
msg.find(".user").text(obj["user"] + " " + matches[1]);
|
||||
msg.find(".user").css("font-weight", "bold");
|
||||
} else {
|
||||
msg.find(".user").text(obj["user"]);
|
||||
msg.find(".message").text(": " + obj["message"]);
|
||||
}
|
||||
} else if (action == "control") {
|
||||
msg.find(".user").text(obj["user"]);
|
||||
msg.find(".message").text(obj["message"]);
|
||||
msg.addClass("control");
|
||||
}
|
||||
|
||||
if (obj["user"] == name) msg.find(".user").addClass("self");
|
||||
container.find("ul").append(msg.show());
|
||||
container.scrollTop(container.find("ul").innerHeight());
|
||||
};
|
||||
|
||||
$("#channel form").submit(function (event) {
|
||||
event.preventDefault();
|
||||
var input = $(this).find(":input");
|
||||
var msg = input.val();
|
||||
if (msg) {
|
||||
ws.send(
|
||||
JSON.stringify({ action: "message", user: name, message: msg }),
|
||||
);
|
||||
}
|
||||
input.val("");
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<style type="text/css" media="screen">
|
||||
* {
|
||||
font-family: Georgia;
|
||||
}
|
||||
a {
|
||||
color: #000;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
div.bordered {
|
||||
margin: 0 auto;
|
||||
margin-top: 100px;
|
||||
width: 600px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
border: 10px solid #ddd;
|
||||
-webkit-border-radius: 20px;
|
||||
}
|
||||
#error {
|
||||
background-color: #ba0000;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
#ask {
|
||||
font-size: 20pt;
|
||||
}
|
||||
#ask input {
|
||||
font-size: 20pt;
|
||||
padding: 10px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
#ask span.join {
|
||||
padding: 10px;
|
||||
background-color: #ddd;
|
||||
-webkit-border-radius: 10px;
|
||||
}
|
||||
#channel {
|
||||
margin-top: 100px;
|
||||
height: 480px;
|
||||
position: relative;
|
||||
}
|
||||
#channel div#descr {
|
||||
position: absolute;
|
||||
left: -10px;
|
||||
top: -190px;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
line-height: 20px;
|
||||
padding: 5px;
|
||||
width: 630px;
|
||||
}
|
||||
div#msgs {
|
||||
overflow-y: scroll;
|
||||
height: 400px;
|
||||
}
|
||||
div#msgs ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-align: left;
|
||||
}
|
||||
div#msgs li {
|
||||
line-height: 20px;
|
||||
}
|
||||
div#msgs li span.user {
|
||||
color: #ff9900;
|
||||
}
|
||||
div#msgs li span.user.self {
|
||||
color: #aa2211;
|
||||
}
|
||||
div#msgs li span.time {
|
||||
float: right;
|
||||
margin-right: 5px;
|
||||
color: #aaa;
|
||||
font-family: "Courier New";
|
||||
font-size: 12px;
|
||||
}
|
||||
div#msgs li.control {
|
||||
text-align: center;
|
||||
}
|
||||
div#msgs li.control span.message {
|
||||
color: #aaa;
|
||||
}
|
||||
div#input {
|
||||
text-align: left;
|
||||
margin-top: 20px;
|
||||
}
|
||||
div#input #message {
|
||||
width: 600px;
|
||||
border: 5px solid #bbb;
|
||||
-webkit-border-radius: 3px;
|
||||
font-size: 30pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="error" class="bordered" style="display: none">
|
||||
This browser has no native WebSocket support.<br />
|
||||
Use a WebKit nightly or Google Chrome.
|
||||
</div>
|
||||
<div id="ask" class="bordered" style="display: none">
|
||||
Name: <input type="text" id="name" />
|
||||
<a href="#"><span class="join">Join!</span></a>
|
||||
</div>
|
||||
<div id="channel" class="bordered" style="display: none">
|
||||
<div id="descr" class="bordered">
|
||||
<strong>Tip:</strong> Open up another browser window to chat.
|
||||
</div>
|
||||
<div id="msgs">
|
||||
<ul>
|
||||
<li class="message" style="display: none">
|
||||
<span class="user"></span><span class="message"></span>
|
||||
<span class="time"></span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="input">
|
||||
<form><input type="text" id="message" /></form>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
192
pkgs/clan-cli/clan_cli/webui/schemas.py
Normal file
192
pkgs/clan-cli/clan_cli/webui/schemas.py
Normal file
@@ -0,0 +1,192 @@
|
||||
# Imports
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from typing import List, Optional
|
||||
|
||||
from pydantic import BaseModel, Field, validator
|
||||
|
||||
from . import sql_models
|
||||
from .db_types import Role, Status
|
||||
|
||||
# Set logger
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# create basemodel
|
||||
class Machine(BaseModel):
|
||||
name: str
|
||||
status: Status
|
||||
|
||||
|
||||
### Create database schema for sql
|
||||
# each section will represent an own table
|
||||
# Entity, Service, Resolution, Eventmessages
|
||||
# The relation between them is as follows:
|
||||
# one Entity can have many Services
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Entity #
|
||||
# #
|
||||
#########################
|
||||
class EntityRolesBase(BaseModel):
|
||||
role: Role = Field(..., example=Role("service_prosumer"))
|
||||
|
||||
|
||||
class EntityRolesCreate(EntityRolesBase):
|
||||
id: int = Field(...)
|
||||
entity_did: str = Field(...)
|
||||
|
||||
|
||||
class EntityRoles(EntityRolesBase):
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class EntityBase(BaseModel):
|
||||
did: str = Field(..., example="did:sov:test:120")
|
||||
name: str = Field(..., example="C1")
|
||||
ip: str = Field(..., example="127.0.0.1")
|
||||
network: str = Field(..., example="255.255.0.0")
|
||||
visible: bool = Field(..., example=True)
|
||||
other: dict = Field(
|
||||
...,
|
||||
example={
|
||||
"network": "Carlos Home Network",
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class EntityCreate(EntityBase):
|
||||
roles: List[Role] = Field(..., example=[Role("service_prosumer"), Role("AP")])
|
||||
|
||||
|
||||
class Entity(EntityBase):
|
||||
attached: bool = Field(...)
|
||||
stop_health_task: bool = Field(...)
|
||||
roles: List[Role]
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
# define a custom getter function for roles
|
||||
@validator("roles", pre=True)
|
||||
def get_roles(cls, v: List[sql_models.EntityRoles | Role]) -> List[Role]:
|
||||
if (
|
||||
isinstance(v, list)
|
||||
and len(v) > 0
|
||||
and isinstance(v[0], sql_models.EntityRoles)
|
||||
):
|
||||
return [x.role for x in v] # type: ignore
|
||||
else:
|
||||
return v # type: ignore
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Service #
|
||||
# #
|
||||
#########################
|
||||
class ServiceUsageBase(BaseModel):
|
||||
times_consumed: int = Field(..., example=2)
|
||||
|
||||
|
||||
class ServiceUsageCreate(ServiceUsageBase):
|
||||
consumer_entity_did: str = Field(..., example="did:sov:test:120")
|
||||
|
||||
|
||||
class ServiceUsage(ServiceUsageCreate):
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class ServiceBase(BaseModel):
|
||||
uuid: str = Field(..., example="bdd640fb-0667-1ad1-1c80-317fa3b1799d")
|
||||
service_name: str = Field(..., example="Carlos Printing")
|
||||
service_type: str = Field(..., example="3D Printing")
|
||||
endpoint_url: str = Field(..., example="http://127.0.0.1:8000")
|
||||
other: dict = Field(..., example={"test": "test"})
|
||||
entity_did: str = Field(..., example="did:sov:test:120")
|
||||
status: dict = Field(..., example={"data": ["draft", "registered"]})
|
||||
action: dict = Field(
|
||||
...,
|
||||
example={
|
||||
"data": [
|
||||
{"name": "register", "path": "/register"},
|
||||
{"name": "deregister", "path": "/deregister"},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
class ServiceCreate(ServiceBase):
|
||||
usage: List[ServiceUsageCreate]
|
||||
|
||||
|
||||
class Service(ServiceBase):
|
||||
usage: List[ServiceUsage]
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
class ServicesByName(BaseModel):
|
||||
services: List[Service]
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Resolution #
|
||||
# #
|
||||
#########################
|
||||
class ResolutionBase(BaseModel):
|
||||
requester_name: str = Field(..., example="C1")
|
||||
requester_did: str = Field(..., example="did:sov:test:1122")
|
||||
resolved_did: str = Field(..., example="did:sov:test:120")
|
||||
other: dict = Field(..., example={"test": "test"})
|
||||
|
||||
|
||||
class ResolutionCreate(ResolutionBase):
|
||||
pass
|
||||
|
||||
|
||||
class Resolution(ResolutionCreate):
|
||||
timestamp: datetime
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Eventmessage #
|
||||
# #
|
||||
#########################
|
||||
class EventmessageBase(BaseModel):
|
||||
timestamp: int = Field(..., example=1234123413)
|
||||
group: int = Field(..., example=1) # event group type (for the label)
|
||||
group_id: int = Field(
|
||||
..., example=12345
|
||||
) # specific to one group needed to enable visually nested groups
|
||||
msg_type: int = Field(..., example=1) # message type for the label
|
||||
src_did: str = Field(..., example="did:sov:test:121")
|
||||
des_did: str = Field(..., example="did:sov:test:120")
|
||||
|
||||
|
||||
class EventmessageCreate(EventmessageBase):
|
||||
msg: dict = Field(..., example={"optinal": "values"}) # optional
|
||||
|
||||
|
||||
class Eventmessage(EventmessageCreate):
|
||||
id: int = Field(...)
|
||||
des_name: Optional[str] = Field(default=None, example="C2")
|
||||
src_name: Optional[str] = Field(default=None, example="C1")
|
||||
msg_type_name: Optional[str] = Field(default=None, example="Request Send")
|
||||
group_name: Optional[str] = Field(default=None, example="Presentation")
|
||||
|
||||
class Config:
|
||||
orm_mode = True
|
||||
@@ -1,5 +1,7 @@
|
||||
# Imports
|
||||
import argparse
|
||||
import logging
|
||||
import multiprocessing as mp
|
||||
import shutil
|
||||
import subprocess
|
||||
import time
|
||||
@@ -9,16 +11,19 @@ from pathlib import Path
|
||||
from threading import Thread
|
||||
from typing import Iterator
|
||||
|
||||
# XXX: can we dynamically load this using nix develop?
|
||||
import uvicorn
|
||||
from pydantic import AnyUrl, IPvAnyAddress
|
||||
from pydantic.tools import parse_obj_as
|
||||
|
||||
import clan_cli.config as config
|
||||
from clan_cli.emulate_fastapi import apps, get_health
|
||||
from clan_cli.errors import ClanError
|
||||
|
||||
# Setting up logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# Function to open the browser for a specified URL
|
||||
def open_browser(base_url: AnyUrl, sub_url: str) -> None:
|
||||
for i in range(5):
|
||||
try:
|
||||
@@ -30,6 +35,7 @@ def open_browser(base_url: AnyUrl, sub_url: str) -> None:
|
||||
_open_browser(url)
|
||||
|
||||
|
||||
# Helper function to open a web browser for a given URL using available browsers
|
||||
def _open_browser(url: AnyUrl) -> subprocess.Popen:
|
||||
for browser in ("firefox", "iceweasel", "iceape", "seamonkey"):
|
||||
if shutil.which(browser):
|
||||
@@ -49,6 +55,7 @@ def _open_browser(url: AnyUrl) -> subprocess.Popen:
|
||||
raise ClanError("No browser found")
|
||||
|
||||
|
||||
# Context manager to spawn the Node.js development server
|
||||
@contextmanager
|
||||
def spawn_node_dev_server(host: IPvAnyAddress, port: int) -> Iterator[None]:
|
||||
log.info("Starting node dev server...")
|
||||
@@ -75,6 +82,7 @@ def spawn_node_dev_server(host: IPvAnyAddress, port: int) -> Iterator[None]:
|
||||
proc.terminate()
|
||||
|
||||
|
||||
# Main function to start the server
|
||||
def start_server(args: argparse.Namespace) -> None:
|
||||
with ExitStack() as stack:
|
||||
headers: list[tuple[str, str]] = []
|
||||
@@ -105,6 +113,48 @@ def start_server(args: argparse.Namespace) -> None:
|
||||
if not args.no_open:
|
||||
Thread(target=open_browser, args=(base_url, args.sub_url)).start()
|
||||
|
||||
# DELETE all data from the database
|
||||
from . import sql_models
|
||||
from .sql_db import engine
|
||||
|
||||
sql_models.Base.metadata.drop_all(engine)
|
||||
|
||||
if args.populate:
|
||||
# pre populate the server with some test data
|
||||
test_dir = Path(__file__).parent.parent.parent / "tests"
|
||||
|
||||
if not test_dir.is_dir():
|
||||
raise ClanError(f"Could not find test dir: {test_dir}")
|
||||
|
||||
test_db_api = test_dir / "test_db_api.py"
|
||||
if not test_db_api.is_file():
|
||||
raise ClanError(f"Could not find test db api: {test_db_api}")
|
||||
|
||||
import subprocess
|
||||
|
||||
cmd = ["pytest", "-s", str(test_db_api)]
|
||||
subprocess.run(cmd, check=True)
|
||||
|
||||
config.host = args.host
|
||||
if args.emulate:
|
||||
# start servers as processes (dlg, ap, c1 and c2 for tests)
|
||||
for app, port in apps:
|
||||
proc = mp.Process(
|
||||
target=uvicorn.run,
|
||||
args=(app,),
|
||||
kwargs={
|
||||
"host": args.host,
|
||||
"port": port,
|
||||
"log_level": args.log_level,
|
||||
},
|
||||
daemon=True,
|
||||
)
|
||||
proc.start()
|
||||
url = f"http://{args.host}:{port}"
|
||||
res = get_health(url=url + "/health")
|
||||
if res is None:
|
||||
raise Exception(f"Couldn't reach {url} after starting server")
|
||||
|
||||
uvicorn.run(
|
||||
"clan_cli.webui.app:app",
|
||||
host=args.host,
|
||||
|
||||
329
pkgs/clan-cli/clan_cli/webui/sql_crud.py
Normal file
329
pkgs/clan-cli/clan_cli/webui/sql_crud.py
Normal file
@@ -0,0 +1,329 @@
|
||||
# Imports
|
||||
from typing import List, Optional
|
||||
|
||||
from sqlalchemy import asc, func
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.sql.expression import true
|
||||
|
||||
from ..errors import ClanError
|
||||
from . import schemas, sql_models
|
||||
|
||||
# Functions to manipulate the tables of the database
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# service #
|
||||
# #
|
||||
#########################
|
||||
def create_service(db: Session, service: schemas.ServiceCreate) -> sql_models.Service:
|
||||
if get_entity_by_did(db, service.entity_did) is None:
|
||||
raise ClanError(f"Entity with did '{service.entity_did}' not found")
|
||||
if get_service_by_uuid(db, service.uuid) is not None:
|
||||
raise ClanError(f"Service with uuid '{service.uuid}' already exists")
|
||||
db_service = sql_models.Service(
|
||||
uuid=service.uuid,
|
||||
service_name=service.service_name,
|
||||
service_type=service.service_type,
|
||||
endpoint_url=service.endpoint_url,
|
||||
status=service.status,
|
||||
other=service.other,
|
||||
entity_did=service.entity_did,
|
||||
action=service.action,
|
||||
)
|
||||
db_usage = []
|
||||
for usage in service.usage:
|
||||
db_usage.append(
|
||||
sql_models.ServiceUsage(
|
||||
times_consumed=usage.times_consumed,
|
||||
consumer_entity_did=usage.consumer_entity_did,
|
||||
)
|
||||
)
|
||||
db_service.usage = db_usage
|
||||
db.add(db_service)
|
||||
db.commit()
|
||||
db.refresh(db_service)
|
||||
return db_service
|
||||
|
||||
|
||||
def set_service_usage(
|
||||
db: Session, service_uuid: str, usages: List[schemas.ServiceUsageCreate]
|
||||
) -> sql_models.Service:
|
||||
db_service = get_service_by_uuid(db, service_uuid)
|
||||
if db_service is None:
|
||||
raise ClanError(f"Service with uuid '{service_uuid}' not found")
|
||||
db_usage = []
|
||||
for usage in usages:
|
||||
db_usage.append(
|
||||
sql_models.ServiceUsage(
|
||||
times_consumed=usage.times_consumed,
|
||||
consumer_entity_did=usage.consumer_entity_did,
|
||||
)
|
||||
)
|
||||
db_service.usage = db_usage
|
||||
db.add(db_service)
|
||||
db.commit()
|
||||
db.refresh(db_service)
|
||||
return db_service
|
||||
|
||||
|
||||
def set_service(
|
||||
db: Session, service_uuid: str, service: schemas.ServiceCreate
|
||||
) -> sql_models.Service:
|
||||
db_service = get_service_by_uuid(db, service_uuid)
|
||||
if db_service is None:
|
||||
raise ClanError(f"Service with uuid '{service_uuid}' not found")
|
||||
db_service.service_name = service.service_name # type: ignore
|
||||
db_service.service_type = service.service_type # type: ignore
|
||||
db_service.endpoint_url = service.endpoint_url # type: ignore
|
||||
db_service.status = service.status # type: ignore
|
||||
db_service.other = service.other # type: ignore
|
||||
db_service.entity_did = service.entity_did # type: ignore
|
||||
db_service.action = service.action # type: ignore
|
||||
db.add(db_service)
|
||||
db.commit()
|
||||
db.refresh(db_service)
|
||||
return db_service
|
||||
|
||||
|
||||
def add_service_usage(
|
||||
db: Session, service_uuid: str, usage: schemas.ServiceUsageCreate
|
||||
) -> sql_models.Service:
|
||||
db_service = get_service_by_uuid(db, service_uuid)
|
||||
if db_service is None:
|
||||
raise ClanError(f"Service with uuid '{service_uuid}' not found")
|
||||
db_service.usage.append(
|
||||
sql_models.ServiceUsage(
|
||||
times_consumed=usage.times_consumed,
|
||||
consumer_entity_did=usage.consumer_entity_did,
|
||||
)
|
||||
)
|
||||
db.add(db_service)
|
||||
db.commit()
|
||||
db.refresh(db_service)
|
||||
return db_service
|
||||
|
||||
|
||||
def increment_service_usage(
|
||||
db: Session, service_uuid: str, consumer_entity_did: str
|
||||
) -> sql_models.ServiceUsage:
|
||||
db_service = get_service_by_uuid(db, service_uuid)
|
||||
if db_service is None:
|
||||
raise ClanError(f"Service with uuid '{service_uuid}' not found")
|
||||
# TODO: Make a query for this
|
||||
for usage in db_service.usage:
|
||||
if usage.consumer_entity_did == consumer_entity_did:
|
||||
usage.times_consumed += 1
|
||||
break
|
||||
db.add(db_service)
|
||||
db.commit()
|
||||
db.refresh(db_service)
|
||||
return db_service
|
||||
|
||||
|
||||
def get_service_by_uuid(db: Session, uuid: str) -> Optional[sql_models.Service]:
|
||||
return db.query(sql_models.Service).filter(sql_models.Service.uuid == uuid).first()
|
||||
|
||||
|
||||
def get_services(
|
||||
db: Session, skip: int = 0, limit: int = 100
|
||||
) -> List[sql_models.Service]:
|
||||
return db.query(sql_models.Service).offset(skip).limit(limit).all()
|
||||
|
||||
|
||||
def get_services_by_entity_did(
|
||||
db: Session, entity_did: str, skip: int = 0, limit: int = 100
|
||||
) -> List[sql_models.Service]:
|
||||
return (
|
||||
db.query(sql_models.Service)
|
||||
.filter(sql_models.Service.entity_did == entity_did)
|
||||
.offset(skip)
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
def delete_service_by_entity_did(db: Session, entity_did: str) -> None:
|
||||
db.query(sql_models.Service).filter(
|
||||
sql_models.Service.entity_did == entity_did
|
||||
).delete()
|
||||
db.commit()
|
||||
|
||||
|
||||
def get_services_without_entity_id(
|
||||
db: Session, entity_did: str, skip: int = 0, limit: int = 100
|
||||
) -> List[sql_models.Service]:
|
||||
return (
|
||||
db.query(sql_models.Service)
|
||||
.filter(sql_models.Service.entity_did != entity_did)
|
||||
.offset(skip)
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Entity #
|
||||
# #
|
||||
#########################
|
||||
def create_entity(db: Session, entity: schemas.EntityCreate) -> sql_models.Entity:
|
||||
if get_entity_by_did(db, entity.did) is not None:
|
||||
raise ClanError(f"Entity with did '{entity.did}' already exists")
|
||||
if get_entity_by_name_or_did(db, entity.name) is not None:
|
||||
raise ClanError(f"Entity with name '{entity.name}' already exists")
|
||||
db_entity = sql_models.Entity(
|
||||
did=entity.did,
|
||||
name=entity.name,
|
||||
ip=entity.ip,
|
||||
network=entity.network,
|
||||
visible=entity.visible,
|
||||
other=entity.other,
|
||||
attached=False,
|
||||
stop_health_task=False,
|
||||
)
|
||||
|
||||
db_roles = []
|
||||
for role in entity.roles:
|
||||
db_roles.append(sql_models.EntityRoles(role=role))
|
||||
|
||||
db_entity.roles = db_roles
|
||||
db.add(db_entity)
|
||||
db.commit()
|
||||
db.refresh(db_entity)
|
||||
return db_entity
|
||||
|
||||
|
||||
def get_entities(
|
||||
db: Session, skip: int = 0, limit: int = 100
|
||||
) -> List[sql_models.Entity]:
|
||||
return db.query(sql_models.Entity).offset(skip).limit(limit).all()
|
||||
|
||||
|
||||
def get_entity_by_did(db: Session, did: str) -> Optional[sql_models.Entity]:
|
||||
return db.query(sql_models.Entity).filter(sql_models.Entity.did == did).first()
|
||||
|
||||
|
||||
def get_entity_by_name_or_did(db: Session, name: str) -> Optional[sql_models.Entity]:
|
||||
return (
|
||||
db.query(sql_models.Entity)
|
||||
.filter((sql_models.Entity.name == name) | (sql_models.Entity.did == name))
|
||||
.first()
|
||||
)
|
||||
|
||||
|
||||
def get_entity_by_role(
|
||||
db: Session, roles: List[schemas.Role]
|
||||
) -> List[sql_models.Entity]:
|
||||
# create a subquery to count the matching roles for each entity
|
||||
subquery = (
|
||||
db.query(
|
||||
sql_models.EntityRoles.entity_did,
|
||||
func.count(sql_models.EntityRoles.role).label("role_count"),
|
||||
)
|
||||
.filter(sql_models.EntityRoles.role.in_(roles))
|
||||
.group_by(sql_models.EntityRoles.entity_did)
|
||||
.subquery()
|
||||
)
|
||||
# join the subquery with the entity table and filter by the role count
|
||||
return (
|
||||
db.query(sql_models.Entity)
|
||||
.join(subquery, sql_models.Entity.did == subquery.c.entity_did)
|
||||
.filter(subquery.c.role_count == len(roles))
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
# get attached
|
||||
def get_attached_entities(
|
||||
db: Session, skip: int = 0, limit: int = 100
|
||||
) -> List[sql_models.Entity]:
|
||||
return (
|
||||
db.query(sql_models.Entity)
|
||||
.filter(sql_models.Entity.attached == true())
|
||||
# https://stackoverflow.com/questions/18998010/flake8-complains-on-boolean-comparison-in-filter-clause
|
||||
.offset(skip)
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
|
||||
|
||||
# Returns same entity if setting didnt changed something
|
||||
def set_stop_health_task(
|
||||
db: Session, entity_did: str, value: bool
|
||||
) -> sql_models.Entity:
|
||||
db_entity = get_entity_by_did(db, entity_did)
|
||||
if db_entity is None:
|
||||
raise ClanError(f"Entity with did '{entity_did}' not found")
|
||||
|
||||
db_entity.stop_health_task = value # type: ignore
|
||||
|
||||
# save changes in db
|
||||
db.add(db_entity)
|
||||
db.commit()
|
||||
db.refresh(db_entity)
|
||||
return db_entity
|
||||
|
||||
|
||||
def set_attached_by_entity_did(
|
||||
db: Session, entity_did: str, attached: bool
|
||||
) -> sql_models.Entity:
|
||||
db_entity = get_entity_by_did(db, entity_did)
|
||||
if db_entity is None:
|
||||
raise ClanError(f"Entity with did '{entity_did}' not found")
|
||||
|
||||
db_entity.attached = attached # type: ignore
|
||||
|
||||
# save changes in db
|
||||
db.add(db_entity)
|
||||
db.commit()
|
||||
db.refresh(db_entity)
|
||||
return db_entity
|
||||
|
||||
|
||||
def delete_entity_by_did(db: Session, did: str) -> None:
|
||||
db.query(sql_models.Entity).filter(sql_models.Entity.did == did).delete()
|
||||
db.commit()
|
||||
|
||||
|
||||
def delete_entity_by_did_recursive(db: Session, did: str) -> None:
|
||||
delete_service_by_entity_did(db, did)
|
||||
delete_entity_by_did(db, did)
|
||||
|
||||
|
||||
#########################
|
||||
# #
|
||||
# Eventmessage #
|
||||
# #
|
||||
#########################
|
||||
|
||||
|
||||
def create_eventmessage(
|
||||
db: Session, eventmsg: schemas.EventmessageCreate
|
||||
) -> sql_models.Eventmessage:
|
||||
db_eventmessage = sql_models.Eventmessage(
|
||||
timestamp=eventmsg.timestamp,
|
||||
group=eventmsg.group,
|
||||
group_id=eventmsg.group_id,
|
||||
msg_type=eventmsg.msg_type,
|
||||
src_did=eventmsg.src_did,
|
||||
des_did=eventmsg.des_did,
|
||||
msg=eventmsg.msg,
|
||||
)
|
||||
db.add(db_eventmessage)
|
||||
db.commit()
|
||||
db.refresh(db_eventmessage)
|
||||
return db_eventmessage
|
||||
|
||||
|
||||
def get_eventmessages(
|
||||
db: Session, skip: int = 0, limit: int = 100
|
||||
) -> List[sql_models.Eventmessage]:
|
||||
# Use order_by and desc to sort by timestamp
|
||||
return (
|
||||
db.query(sql_models.Eventmessage)
|
||||
.order_by(asc(sql_models.Eventmessage.timestamp))
|
||||
.offset(skip)
|
||||
.limit(limit)
|
||||
.all()
|
||||
)
|
||||
25
pkgs/clan-cli/clan_cli/webui/sql_db.py
Normal file
25
pkgs/clan-cli/clan_cli/webui/sql_db.py
Normal file
@@ -0,0 +1,25 @@
|
||||
# Imports
|
||||
from typing import Generator
|
||||
|
||||
from sqlalchemy import create_engine
|
||||
|
||||
# from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy.orm import Session, declarative_base, sessionmaker
|
||||
|
||||
URL = "sqlite:///./sql_app.db"
|
||||
|
||||
# Create db engine
|
||||
|
||||
engine = create_engine(URL, connect_args={"check_same_thread": False})
|
||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
# Dependency to start a clean thread of the db
|
||||
def get_db() -> Generator[Session, None, None]:
|
||||
db = SessionLocal()
|
||||
try:
|
||||
yield db
|
||||
finally:
|
||||
db.close()
|
||||
118
pkgs/clan-cli/clan_cli/webui/sql_models.py
Normal file
118
pkgs/clan-cli/clan_cli/webui/sql_models.py
Normal file
@@ -0,0 +1,118 @@
|
||||
from sqlalchemy import JSON, Boolean, Column, Enum, ForeignKey, Integer, String, Text
|
||||
from sqlalchemy.orm import relationship
|
||||
|
||||
from .db_types import Role
|
||||
from .sql_db import Base
|
||||
|
||||
|
||||
# SQLAlchemy model for the "entities" table
|
||||
class Entity(Base):
|
||||
__tablename__ = "entities"
|
||||
|
||||
## Queryable body ##
|
||||
# Primary Key
|
||||
did = Column(String, primary_key=True, index=True)
|
||||
# Indexed Columns
|
||||
name = Column(String, index=True, unique=True)
|
||||
ip = Column(String, index=True)
|
||||
network = Column(String, index=True)
|
||||
attached = Column(Boolean, index=True)
|
||||
visible = Column(Boolean, index=True)
|
||||
stop_health_task = Column(Boolean)
|
||||
|
||||
## Non queryable body ##
|
||||
# JSON field for additional non-queryable data
|
||||
other = Column(JSON)
|
||||
|
||||
## Relations ##
|
||||
# One-to-Many relationship with "services" table
|
||||
services = relationship("Service", back_populates="entity")
|
||||
# One-to-Many relationship with "entity_roles" table
|
||||
roles = relationship("EntityRoles", back_populates="entity")
|
||||
# One-to-Many relationship with "service_usage" table
|
||||
consumes = relationship("ServiceUsage", back_populates="consumer_entity")
|
||||
|
||||
|
||||
# SQLAlchemy model for the "entity_roles" table
|
||||
class EntityRoles(Base):
|
||||
__tablename__ = "entity_roles"
|
||||
|
||||
## Queryable body ##
|
||||
# Primary Key
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
# Foreign Key
|
||||
entity_did = Column(String, ForeignKey("entities.did"))
|
||||
# Enum field for role
|
||||
role = Column(Enum(Role), index=True, nullable=False) # type: ignore
|
||||
|
||||
## Relations ##
|
||||
# Many-to-One relationship with "entities" table
|
||||
entity = relationship("Entity", back_populates="roles")
|
||||
|
||||
|
||||
# SQLAlchemy model for the "service_usage" table
|
||||
class ServiceUsage(Base):
|
||||
__tablename__ = "service_usage"
|
||||
|
||||
## Queryable body ##
|
||||
# Primary Key
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
# Foreign Key
|
||||
consumer_entity_did = Column(String, ForeignKey("entities.did"))
|
||||
# Many-to-One relationship with "entities" table
|
||||
consumer_entity = relationship("Entity", back_populates="consumes")
|
||||
times_consumed = Column(Integer, index=True, nullable=False)
|
||||
|
||||
service_uuid = Column(String, ForeignKey("services.uuid"))
|
||||
# Many-to-One relationship with "services" table
|
||||
service = relationship("Service", back_populates="usage")
|
||||
|
||||
|
||||
# SQLAlchemy model for the "services" table
|
||||
class Service(Base):
|
||||
__tablename__ = "services"
|
||||
|
||||
# Queryable body
|
||||
# Primary Key
|
||||
uuid = Column(Text(length=36), primary_key=True, index=True)
|
||||
service_name = Column(String, index=True)
|
||||
service_type = Column(String, index=True)
|
||||
endpoint_url = Column(String, index=True)
|
||||
|
||||
## Non queryable body ##
|
||||
# JSON fields for additional non-queryable data
|
||||
other = Column(JSON)
|
||||
status = Column(JSON, index=True)
|
||||
action = Column(JSON, index=True)
|
||||
|
||||
## Relations ##
|
||||
# One-to-Many relationship with "entities" table
|
||||
entity = relationship("Entity", back_populates="services")
|
||||
entity_did = Column(String, ForeignKey("entities.did"))
|
||||
|
||||
# One-to-Many relationship with "service_usage" table
|
||||
usage = relationship("ServiceUsage", back_populates="service")
|
||||
|
||||
|
||||
# SQLAlchemy model for the "eventmessages" table
|
||||
class Eventmessage(Base):
|
||||
__tablename__ = "eventmessages"
|
||||
|
||||
## Queryable body ##
|
||||
# Primary Key
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
timestamp = Column(Integer, index=True)
|
||||
group = Column(Integer, index=True)
|
||||
group_id = Column(Integer, index=True)
|
||||
msg_type = Column(Integer, index=True) # message type for the label
|
||||
src_did = Column(String, index=True)
|
||||
des_did = Column(String, index=True)
|
||||
|
||||
## Non queryable body ##
|
||||
# JSON field for additional non-queryable data
|
||||
msg = Column(JSON)
|
||||
|
||||
## Relations ##
|
||||
# One-to-Many relationship with "entities" table
|
||||
# One entity can send many messages
|
||||
# (Note: The comment is incomplete and can be extended based on the relationship)
|
||||
37
pkgs/clan-cli/clan_cli/webui/tags.py
Normal file
37
pkgs/clan-cli/clan_cli/webui/tags.py
Normal file
@@ -0,0 +1,37 @@
|
||||
from enum import Enum
|
||||
from typing import Any, Dict, List
|
||||
|
||||
|
||||
class Tags(Enum):
|
||||
services = "services"
|
||||
entities = "entities"
|
||||
repositories = "repositories"
|
||||
resolutions = "resolution"
|
||||
eventmessages = "eventmessages"
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.value
|
||||
|
||||
|
||||
tags_metadata: List[Dict[str, Any]] = [
|
||||
{
|
||||
"name": str(Tags.services),
|
||||
"description": "Operations on a service.",
|
||||
},
|
||||
{
|
||||
"name": str(Tags.repositories),
|
||||
"description": "Operations on a repository.",
|
||||
},
|
||||
{
|
||||
"name": str(Tags.entities),
|
||||
"description": "Operations on an entity.",
|
||||
},
|
||||
{
|
||||
"name": str(Tags.resolutions),
|
||||
"description": "Operations on a resolution.",
|
||||
},
|
||||
{
|
||||
"name": str(Tags.eventmessages),
|
||||
"description": "Operations for event messages.",
|
||||
},
|
||||
]
|
||||
@@ -1,5 +1,4 @@
|
||||
{ age
|
||||
, lib
|
||||
{ lib
|
||||
, argcomplete
|
||||
, fastapi
|
||||
, uvicorn
|
||||
@@ -8,7 +7,6 @@
|
||||
, openssh
|
||||
, pytest
|
||||
, pytest-cov
|
||||
, pytest-xdist
|
||||
, pytest-subprocess
|
||||
, pytest-timeout
|
||||
, remote-pdb
|
||||
@@ -16,24 +14,24 @@
|
||||
, python3
|
||||
, runCommand
|
||||
, setuptools
|
||||
, sops
|
||||
, stdenv
|
||||
, wheel
|
||||
, fakeroot
|
||||
, rsync
|
||||
, ui-assets
|
||||
, bash
|
||||
, sshpass
|
||||
, zbar
|
||||
, tor
|
||||
, git
|
||||
, nixpkgs
|
||||
, makeDesktopItem
|
||||
, copyDesktopItems
|
||||
, qemu
|
||||
, gnupg
|
||||
, e2fsprogs
|
||||
, mypy
|
||||
, sqlalchemy
|
||||
, websockets
|
||||
, broadcaster
|
||||
, aenum
|
||||
, dateutil
|
||||
, urllib3
|
||||
}:
|
||||
let
|
||||
|
||||
@@ -41,13 +39,15 @@ let
|
||||
argcomplete # optional dependency: if not enabled, shell completion will not work
|
||||
fastapi
|
||||
uvicorn # optional dependencies: if not enabled, webui subcommand will not work
|
||||
sqlalchemy
|
||||
websockets
|
||||
broadcaster
|
||||
];
|
||||
|
||||
pytestDependencies = runtimeDependencies ++ dependencies ++ [
|
||||
pytest
|
||||
pytest-cov
|
||||
pytest-subprocess
|
||||
pytest-xdist
|
||||
pytest-timeout
|
||||
remote-pdb
|
||||
ipdb
|
||||
@@ -55,6 +55,10 @@ let
|
||||
git
|
||||
gnupg
|
||||
stdenv.cc
|
||||
# openapi client deps
|
||||
dateutil
|
||||
aenum
|
||||
urllib3
|
||||
];
|
||||
|
||||
# Optional dependencies for clan cli, we re-expose them here to make sure they all build.
|
||||
@@ -62,17 +66,9 @@ let
|
||||
bash
|
||||
nix
|
||||
fakeroot
|
||||
openssh
|
||||
sshpass
|
||||
zbar
|
||||
tor
|
||||
age
|
||||
rsync
|
||||
sops
|
||||
git
|
||||
mypy
|
||||
qemu
|
||||
e2fsprogs
|
||||
];
|
||||
|
||||
runtimeDependenciesAsSet = builtins.listToAttrs (builtins.map (p: lib.nameValuePair (lib.getName p.name) p) runtimeDependencies);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{ inputs, ... }:
|
||||
{
|
||||
perSystem = { self', pkgs, ... }: {
|
||||
perSystem = { self', pkgs, system, ... }: {
|
||||
devShells.clan-cli = pkgs.callPackage ./shell.nix {
|
||||
inherit (self'.packages) clan-cli ui-assets nix-unit;
|
||||
};
|
||||
@@ -8,9 +8,23 @@
|
||||
clan-cli = pkgs.python3.pkgs.callPackage ./default.nix {
|
||||
inherit (self'.packages) ui-assets;
|
||||
inherit (inputs) nixpkgs;
|
||||
inherit (inputs.nixpkgs-for-iosl.legacyPackages.${system}.python3Packages) broadcaster;
|
||||
};
|
||||
inherit (self'.packages.clan-cli) clan-openapi;
|
||||
default = self'.packages.clan-cli;
|
||||
|
||||
|
||||
clan-docker = pkgs.dockerTools.buildImage {
|
||||
name = "clan-docker";
|
||||
tag = "latest";
|
||||
created = "now";
|
||||
config = {
|
||||
Cmd = [ "${self'.packages.clan-cli}/bin/clan" "webui" "--no-open" "--host" "0.0.0.0" ];
|
||||
ExposedPorts = {
|
||||
"2979/tcp" = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
checks = self'.packages.clan-cli.tests;
|
||||
|
||||
9
pkgs/clan-cli/push_docker.sh
Executable file
9
pkgs/clan-cli/push_docker.sh
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# shellcheck shell=bash
|
||||
set -euo pipefail
|
||||
|
||||
docker login git.tu-berlin.de:5000
|
||||
docker load < result
|
||||
docker image tag clan-docker:latest git.tu-berlin.de:5000/internet-of-services-lab/service-aware-network-front-end:latest
|
||||
docker image push git.tu-berlin.de:5000/internet-of-services-lab/service-aware-network-front-end:latest
|
||||
@@ -21,7 +21,7 @@ testpaths = "tests"
|
||||
faulthandler_timeout = 60
|
||||
log_level = "DEBUG"
|
||||
log_format = "%(levelname)s: %(message)s"
|
||||
addopts = "--cov . --cov-report term --cov-report html:.reports/html --no-cov-on-fail --durations 5 --color=yes --maxfail=1 --new-first -nauto" # Add --pdb for debugging
|
||||
addopts = "--cov . --cov-report term --cov-report html:.reports/html --no-cov-on-fail --durations 5 --color=yes --maxfail=1 --new-first" # Add --pdb for debugging
|
||||
norecursedirs = "tests/helpers"
|
||||
markers = [ "impure" ]
|
||||
|
||||
@@ -31,7 +31,14 @@ warn_redundant_casts = true
|
||||
disallow_untyped_calls = true
|
||||
disallow_untyped_defs = true
|
||||
no_implicit_optional = true
|
||||
exclude = "clan_cli.nixpkgs"
|
||||
follow_imports = "normal"
|
||||
exclude = [
|
||||
"clan_cli.nixpkgs",
|
||||
]
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "openapi_client.*"
|
||||
ignore_errors = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "argcomplete.*"
|
||||
@@ -49,15 +56,20 @@ ignore_missing_imports = true
|
||||
module = "pytest.*"
|
||||
ignore_missing_imports = true
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "anyio.*"
|
||||
ignore_missing_imports = true
|
||||
|
||||
|
||||
[[tool.mypy.overrides]]
|
||||
module = "setuptools.*"
|
||||
ignore_missing_imports = true
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 88
|
||||
|
||||
select = [ "E", "F", "I", "N"]
|
||||
ignore = [ "E501" ]
|
||||
ignore = [ "E501", "N805" ]
|
||||
exclude = ["tests/openapi_client"]
|
||||
|
||||
[tool.black]
|
||||
line-length = 88
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{ nix-unit, clan-cli, ui-assets, system, mkShell, writeScriptBin, openssh, ruff, python3 }:
|
||||
{ nix-unit, clan-cli, openapi-generator-cli, ui-assets, system, mkShell, writeScriptBin, openssh, ruff, python3 }:
|
||||
let
|
||||
checkScript = writeScriptBin "check" ''
|
||||
nix build .#checks.${system}.{treefmt,clan-pytest} -L "$@"
|
||||
@@ -19,6 +19,7 @@ mkShell {
|
||||
openssh
|
||||
ruff
|
||||
clan-cli.checkPython
|
||||
openapi-generator-cli
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
|
||||
@@ -1,9 +1,63 @@
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
import sys
|
||||
import time
|
||||
import urllib.request
|
||||
from multiprocessing import Process
|
||||
from typing import Generator
|
||||
from urllib.error import URLError
|
||||
|
||||
import pytest
|
||||
import uvicorn
|
||||
from fastapi.testclient import TestClient
|
||||
from openapi_client import ApiClient, Configuration
|
||||
from ports import PortFunction
|
||||
|
||||
import clan_cli.config as config
|
||||
from clan_cli.webui.app import app
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def api() -> TestClient:
|
||||
def test_client() -> TestClient:
|
||||
return TestClient(app)
|
||||
|
||||
|
||||
def get_health(*, url: str, max_retries: int = 20, delay: float = 0.2) -> str | None:
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
with urllib.request.urlopen(url) as response:
|
||||
return response.read()
|
||||
except URLError as e:
|
||||
print(f"Attempt {attempt + 1} failed: {e.reason}", file=sys.stderr)
|
||||
time.sleep(delay)
|
||||
return None
|
||||
|
||||
|
||||
# Pytest fixture to run the server in a separate process
|
||||
# server
|
||||
@pytest.fixture(scope="session")
|
||||
def server_url(unused_tcp_port: PortFunction) -> Generator[str, None, None]:
|
||||
port = unused_tcp_port()
|
||||
host = config.host
|
||||
proc = Process(
|
||||
target=uvicorn.run,
|
||||
args=(app,),
|
||||
kwargs={"host": host, "port": port, "log_level": "info"},
|
||||
daemon=True,
|
||||
)
|
||||
proc.start()
|
||||
|
||||
url = f"http://{host}:{port}"
|
||||
res = get_health(url=url + "/health")
|
||||
if res is None:
|
||||
raise Exception(f"Couldn't reach {url} after starting server")
|
||||
|
||||
yield url
|
||||
proc.terminate()
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def api_client(server_url: str) -> Generator[ApiClient, None, None]:
|
||||
configuration = Configuration(host=server_url)
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with ApiClient(configuration) as api_client:
|
||||
yield api_client
|
||||
|
||||
53
pkgs/clan-cli/tests/openapi_client/__init__.py
Normal file
53
pkgs/clan-cli/tests/openapi_client/__init__.py
Normal file
@@ -0,0 +1,53 @@
|
||||
# coding: utf-8
|
||||
|
||||
# flake8: noqa
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
__version__ = "1.0.0"
|
||||
|
||||
# import apis into sdk package
|
||||
from openapi_client.api.default_api import DefaultApi
|
||||
from openapi_client.api.entities_api import EntitiesApi
|
||||
from openapi_client.api.eventmessages_api import EventmessagesApi
|
||||
from openapi_client.api.repositories_api import RepositoriesApi
|
||||
from openapi_client.api.resolution_api import ResolutionApi
|
||||
from openapi_client.api.services_api import ServicesApi
|
||||
|
||||
# import ApiClient
|
||||
from openapi_client.api_response import ApiResponse
|
||||
from openapi_client.api_client import ApiClient
|
||||
from openapi_client.configuration import Configuration
|
||||
from openapi_client.exceptions import OpenApiException
|
||||
from openapi_client.exceptions import ApiTypeError
|
||||
from openapi_client.exceptions import ApiValueError
|
||||
from openapi_client.exceptions import ApiKeyError
|
||||
from openapi_client.exceptions import ApiAttributeError
|
||||
from openapi_client.exceptions import ApiException
|
||||
|
||||
# import models into sdk package
|
||||
from openapi_client.models.entity import Entity
|
||||
from openapi_client.models.entity_create import EntityCreate
|
||||
from openapi_client.models.eventmessage import Eventmessage
|
||||
from openapi_client.models.eventmessage_create import EventmessageCreate
|
||||
from openapi_client.models.http_validation_error import HTTPValidationError
|
||||
from openapi_client.models.machine import Machine
|
||||
from openapi_client.models.resolution import Resolution
|
||||
from openapi_client.models.role import Role
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.service_create import ServiceCreate
|
||||
from openapi_client.models.service_usage import ServiceUsage
|
||||
from openapi_client.models.service_usage_create import ServiceUsageCreate
|
||||
from openapi_client.models.status import Status
|
||||
from openapi_client.models.validation_error import ValidationError
|
||||
from openapi_client.models.validation_error_loc_inner import ValidationErrorLocInner
|
||||
10
pkgs/clan-cli/tests/openapi_client/api/__init__.py
Normal file
10
pkgs/clan-cli/tests/openapi_client/api/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
||||
# flake8: noqa
|
||||
|
||||
# import apis into api package
|
||||
from openapi_client.api.default_api import DefaultApi
|
||||
from openapi_client.api.entities_api import EntitiesApi
|
||||
from openapi_client.api.eventmessages_api import EventmessagesApi
|
||||
from openapi_client.api.repositories_api import RepositoriesApi
|
||||
from openapi_client.api.resolution_api import ResolutionApi
|
||||
from openapi_client.api.services_api import ServicesApi
|
||||
|
||||
439
pkgs/clan-cli/tests/openapi_client/api/default_api.py
Normal file
439
pkgs/clan-cli/tests/openapi_client/api/default_api.py
Normal file
@@ -0,0 +1,439 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import re # noqa: F401
|
||||
import io
|
||||
import warnings
|
||||
|
||||
from pydantic import validate_arguments, ValidationError
|
||||
|
||||
from pydantic import StrictStr
|
||||
|
||||
from openapi_client.models.machine import Machine
|
||||
|
||||
from openapi_client.api_client import ApiClient
|
||||
from openapi_client.api_response import ApiResponse
|
||||
from openapi_client.exceptions import ( # noqa: F401
|
||||
ApiTypeError,
|
||||
ApiValueError
|
||||
)
|
||||
|
||||
|
||||
class DefaultApi:
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator
|
||||
Ref: https://openapi-generator.tech
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, api_client=None) -> None:
|
||||
if api_client is None:
|
||||
api_client = ApiClient.get_default()
|
||||
self.api_client = api_client
|
||||
|
||||
@validate_arguments
|
||||
def get_emulated_enpoints(self, **kwargs) -> str: # noqa: E501
|
||||
"""Get Emulated Enpoints # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_emulated_enpoints(async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
If one number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: str
|
||||
"""
|
||||
kwargs['_return_http_data_only'] = True
|
||||
if '_preload_content' in kwargs:
|
||||
message = "Error! Please call the get_emulated_enpoints_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
|
||||
raise ValueError(message)
|
||||
return self.get_emulated_enpoints_with_http_info(**kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def get_emulated_enpoints_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Get Emulated Enpoints # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_emulated_enpoints_with_http_info(async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:type _preload_content: bool, optional
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:type _return_http_data_only: bool, optional
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:type _content_type: string, optional: force content-type for the request
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: tuple(str, status_code(int), headers(HTTPHeaderDict))
|
||||
"""
|
||||
|
||||
_params = locals()
|
||||
|
||||
_all_params = [
|
||||
]
|
||||
_all_params.extend(
|
||||
[
|
||||
'async_req',
|
||||
'_return_http_data_only',
|
||||
'_preload_content',
|
||||
'_request_timeout',
|
||||
'_request_auth',
|
||||
'_content_type',
|
||||
'_headers'
|
||||
]
|
||||
)
|
||||
|
||||
# validate the arguments
|
||||
for _key, _val in _params['kwargs'].items():
|
||||
if _key not in _all_params:
|
||||
raise ApiTypeError(
|
||||
"Got an unexpected keyword argument '%s'"
|
||||
" to method get_emulated_enpoints" % _key
|
||||
)
|
||||
_params[_key] = _val
|
||||
del _params['kwargs']
|
||||
|
||||
_collection_formats = {}
|
||||
|
||||
# process the path parameters
|
||||
_path_params = {}
|
||||
|
||||
# process the query parameters
|
||||
_query_params = []
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
# process the form parameters
|
||||
_form_params = []
|
||||
_files = {}
|
||||
# process the body parameter
|
||||
_body_params = None
|
||||
# set the HTTP header `Accept`
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
['text/html']) # noqa: E501
|
||||
|
||||
# authentication setting
|
||||
_auth_settings = [] # noqa: E501
|
||||
|
||||
_response_types_map = {
|
||||
'200': "str",
|
||||
}
|
||||
|
||||
return self.api_client.call_api(
|
||||
'/emulate', 'GET',
|
||||
_path_params,
|
||||
_query_params,
|
||||
_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
response_types_map=_response_types_map,
|
||||
auth_settings=_auth_settings,
|
||||
async_req=_params.get('async_req'),
|
||||
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
|
||||
_preload_content=_params.get('_preload_content', True),
|
||||
_request_timeout=_params.get('_request_timeout'),
|
||||
collection_formats=_collection_formats,
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
|
||||
@validate_arguments
|
||||
def health(self, **kwargs) -> Machine: # noqa: E501
|
||||
"""Health # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.health(async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
If one number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: Machine
|
||||
"""
|
||||
kwargs['_return_http_data_only'] = True
|
||||
if '_preload_content' in kwargs:
|
||||
message = "Error! Please call the health_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
|
||||
raise ValueError(message)
|
||||
return self.health_with_http_info(**kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def health_with_http_info(self, **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Health # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.health_with_http_info(async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:type _preload_content: bool, optional
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:type _return_http_data_only: bool, optional
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:type _content_type: string, optional: force content-type for the request
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: tuple(Machine, status_code(int), headers(HTTPHeaderDict))
|
||||
"""
|
||||
|
||||
_params = locals()
|
||||
|
||||
_all_params = [
|
||||
]
|
||||
_all_params.extend(
|
||||
[
|
||||
'async_req',
|
||||
'_return_http_data_only',
|
||||
'_preload_content',
|
||||
'_request_timeout',
|
||||
'_request_auth',
|
||||
'_content_type',
|
||||
'_headers'
|
||||
]
|
||||
)
|
||||
|
||||
# validate the arguments
|
||||
for _key, _val in _params['kwargs'].items():
|
||||
if _key not in _all_params:
|
||||
raise ApiTypeError(
|
||||
"Got an unexpected keyword argument '%s'"
|
||||
" to method health" % _key
|
||||
)
|
||||
_params[_key] = _val
|
||||
del _params['kwargs']
|
||||
|
||||
_collection_formats = {}
|
||||
|
||||
# process the path parameters
|
||||
_path_params = {}
|
||||
|
||||
# process the query parameters
|
||||
_query_params = []
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
# process the form parameters
|
||||
_form_params = []
|
||||
_files = {}
|
||||
# process the body parameter
|
||||
_body_params = None
|
||||
# set the HTTP header `Accept`
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
['application/json']) # noqa: E501
|
||||
|
||||
# authentication setting
|
||||
_auth_settings = [] # noqa: E501
|
||||
|
||||
_response_types_map = {
|
||||
'200': "Machine",
|
||||
}
|
||||
|
||||
return self.api_client.call_api(
|
||||
'/health', 'GET',
|
||||
_path_params,
|
||||
_query_params,
|
||||
_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
response_types_map=_response_types_map,
|
||||
auth_settings=_auth_settings,
|
||||
async_req=_params.get('async_req'),
|
||||
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
|
||||
_preload_content=_params.get('_preload_content', True),
|
||||
_request_timeout=_params.get('_request_timeout'),
|
||||
collection_formats=_collection_formats,
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
|
||||
@validate_arguments
|
||||
def root(self, path_name : StrictStr, **kwargs) -> None: # noqa: E501
|
||||
"""Root # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.root(path_name, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param path_name: (required)
|
||||
:type path_name: str
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
If one number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: None
|
||||
"""
|
||||
kwargs['_return_http_data_only'] = True
|
||||
if '_preload_content' in kwargs:
|
||||
message = "Error! Please call the root_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
|
||||
raise ValueError(message)
|
||||
return self.root_with_http_info(path_name, **kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def root_with_http_info(self, path_name : StrictStr, **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Root # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.root_with_http_info(path_name, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param path_name: (required)
|
||||
:type path_name: str
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:type _preload_content: bool, optional
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:type _return_http_data_only: bool, optional
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:type _content_type: string, optional: force content-type for the request
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: None
|
||||
"""
|
||||
|
||||
_params = locals()
|
||||
|
||||
_all_params = [
|
||||
'path_name'
|
||||
]
|
||||
_all_params.extend(
|
||||
[
|
||||
'async_req',
|
||||
'_return_http_data_only',
|
||||
'_preload_content',
|
||||
'_request_timeout',
|
||||
'_request_auth',
|
||||
'_content_type',
|
||||
'_headers'
|
||||
]
|
||||
)
|
||||
|
||||
# validate the arguments
|
||||
for _key, _val in _params['kwargs'].items():
|
||||
if _key not in _all_params:
|
||||
raise ApiTypeError(
|
||||
"Got an unexpected keyword argument '%s'"
|
||||
" to method root" % _key
|
||||
)
|
||||
_params[_key] = _val
|
||||
del _params['kwargs']
|
||||
|
||||
_collection_formats = {}
|
||||
|
||||
# process the path parameters
|
||||
_path_params = {}
|
||||
if _params['path_name']:
|
||||
_path_params['path_name'] = _params['path_name']
|
||||
|
||||
|
||||
# process the query parameters
|
||||
_query_params = []
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
# process the form parameters
|
||||
_form_params = []
|
||||
_files = {}
|
||||
# process the body parameter
|
||||
_body_params = None
|
||||
# set the HTTP header `Accept`
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
['application/json']) # noqa: E501
|
||||
|
||||
# authentication setting
|
||||
_auth_settings = [] # noqa: E501
|
||||
|
||||
_response_types_map = {}
|
||||
|
||||
return self.api_client.call_api(
|
||||
'/{path_name}', 'GET',
|
||||
_path_params,
|
||||
_query_params,
|
||||
_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
response_types_map=_response_types_map,
|
||||
auth_settings=_auth_settings,
|
||||
async_req=_params.get('async_req'),
|
||||
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
|
||||
_preload_content=_params.get('_preload_content', True),
|
||||
_request_timeout=_params.get('_request_timeout'),
|
||||
collection_formats=_collection_formats,
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
1354
pkgs/clan-cli/tests/openapi_client/api/entities_api.py
Normal file
1354
pkgs/clan-cli/tests/openapi_client/api/entities_api.py
Normal file
File diff suppressed because it is too large
Load Diff
336
pkgs/clan-cli/tests/openapi_client/api/eventmessages_api.py
Normal file
336
pkgs/clan-cli/tests/openapi_client/api/eventmessages_api.py
Normal file
@@ -0,0 +1,336 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import re # noqa: F401
|
||||
import io
|
||||
import warnings
|
||||
|
||||
from pydantic import validate_arguments, ValidationError
|
||||
|
||||
from pydantic import StrictInt
|
||||
|
||||
from typing import Optional
|
||||
|
||||
from openapi_client.models.eventmessage import Eventmessage
|
||||
from openapi_client.models.eventmessage_create import EventmessageCreate
|
||||
|
||||
from openapi_client.api_client import ApiClient
|
||||
from openapi_client.api_response import ApiResponse
|
||||
from openapi_client.exceptions import ( # noqa: F401
|
||||
ApiTypeError,
|
||||
ApiValueError
|
||||
)
|
||||
|
||||
|
||||
class EventmessagesApi:
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator
|
||||
Ref: https://openapi-generator.tech
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, api_client=None) -> None:
|
||||
if api_client is None:
|
||||
api_client = ApiClient.get_default()
|
||||
self.api_client = api_client
|
||||
|
||||
@validate_arguments
|
||||
def create_eventmessage(self, eventmessage_create : EventmessageCreate, **kwargs) -> Eventmessage: # noqa: E501
|
||||
"""Create Eventmessage # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.create_eventmessage(eventmessage_create, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param eventmessage_create: (required)
|
||||
:type eventmessage_create: EventmessageCreate
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
If one number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: Eventmessage
|
||||
"""
|
||||
kwargs['_return_http_data_only'] = True
|
||||
if '_preload_content' in kwargs:
|
||||
message = "Error! Please call the create_eventmessage_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
|
||||
raise ValueError(message)
|
||||
return self.create_eventmessage_with_http_info(eventmessage_create, **kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def create_eventmessage_with_http_info(self, eventmessage_create : EventmessageCreate, **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Create Eventmessage # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.create_eventmessage_with_http_info(eventmessage_create, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param eventmessage_create: (required)
|
||||
:type eventmessage_create: EventmessageCreate
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:type _preload_content: bool, optional
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:type _return_http_data_only: bool, optional
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:type _content_type: string, optional: force content-type for the request
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: tuple(Eventmessage, status_code(int), headers(HTTPHeaderDict))
|
||||
"""
|
||||
|
||||
_params = locals()
|
||||
|
||||
_all_params = [
|
||||
'eventmessage_create'
|
||||
]
|
||||
_all_params.extend(
|
||||
[
|
||||
'async_req',
|
||||
'_return_http_data_only',
|
||||
'_preload_content',
|
||||
'_request_timeout',
|
||||
'_request_auth',
|
||||
'_content_type',
|
||||
'_headers'
|
||||
]
|
||||
)
|
||||
|
||||
# validate the arguments
|
||||
for _key, _val in _params['kwargs'].items():
|
||||
if _key not in _all_params:
|
||||
raise ApiTypeError(
|
||||
"Got an unexpected keyword argument '%s'"
|
||||
" to method create_eventmessage" % _key
|
||||
)
|
||||
_params[_key] = _val
|
||||
del _params['kwargs']
|
||||
|
||||
_collection_formats = {}
|
||||
|
||||
# process the path parameters
|
||||
_path_params = {}
|
||||
|
||||
# process the query parameters
|
||||
_query_params = []
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
# process the form parameters
|
||||
_form_params = []
|
||||
_files = {}
|
||||
# process the body parameter
|
||||
_body_params = None
|
||||
if _params['eventmessage_create'] is not None:
|
||||
_body_params = _params['eventmessage_create']
|
||||
|
||||
# set the HTTP header `Accept`
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
['application/json']) # noqa: E501
|
||||
|
||||
# set the HTTP header `Content-Type`
|
||||
_content_types_list = _params.get('_content_type',
|
||||
self.api_client.select_header_content_type(
|
||||
['application/json']))
|
||||
if _content_types_list:
|
||||
_header_params['Content-Type'] = _content_types_list
|
||||
|
||||
# authentication setting
|
||||
_auth_settings = [] # noqa: E501
|
||||
|
||||
_response_types_map = {
|
||||
'200': "Eventmessage",
|
||||
'422': "HTTPValidationError",
|
||||
}
|
||||
|
||||
return self.api_client.call_api(
|
||||
'/api/v1/event_message', 'POST',
|
||||
_path_params,
|
||||
_query_params,
|
||||
_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
response_types_map=_response_types_map,
|
||||
auth_settings=_auth_settings,
|
||||
async_req=_params.get('async_req'),
|
||||
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
|
||||
_preload_content=_params.get('_preload_content', True),
|
||||
_request_timeout=_params.get('_request_timeout'),
|
||||
collection_formats=_collection_formats,
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
|
||||
@validate_arguments
|
||||
def get_all_eventmessages(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> None: # noqa: E501
|
||||
"""Get All Eventmessages # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_all_eventmessages(skip, limit, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param skip:
|
||||
:type skip: int
|
||||
:param limit:
|
||||
:type limit: int
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
If one number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: None
|
||||
"""
|
||||
kwargs['_return_http_data_only'] = True
|
||||
if '_preload_content' in kwargs:
|
||||
message = "Error! Please call the get_all_eventmessages_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
|
||||
raise ValueError(message)
|
||||
return self.get_all_eventmessages_with_http_info(skip, limit, **kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def get_all_eventmessages_with_http_info(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Get All Eventmessages # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_all_eventmessages_with_http_info(skip, limit, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param skip:
|
||||
:type skip: int
|
||||
:param limit:
|
||||
:type limit: int
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:type _preload_content: bool, optional
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:type _return_http_data_only: bool, optional
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:type _content_type: string, optional: force content-type for the request
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: None
|
||||
"""
|
||||
|
||||
_params = locals()
|
||||
|
||||
_all_params = [
|
||||
'skip',
|
||||
'limit'
|
||||
]
|
||||
_all_params.extend(
|
||||
[
|
||||
'async_req',
|
||||
'_return_http_data_only',
|
||||
'_preload_content',
|
||||
'_request_timeout',
|
||||
'_request_auth',
|
||||
'_content_type',
|
||||
'_headers'
|
||||
]
|
||||
)
|
||||
|
||||
# validate the arguments
|
||||
for _key, _val in _params['kwargs'].items():
|
||||
if _key not in _all_params:
|
||||
raise ApiTypeError(
|
||||
"Got an unexpected keyword argument '%s'"
|
||||
" to method get_all_eventmessages" % _key
|
||||
)
|
||||
_params[_key] = _val
|
||||
del _params['kwargs']
|
||||
|
||||
_collection_formats = {}
|
||||
|
||||
# process the path parameters
|
||||
_path_params = {}
|
||||
|
||||
# process the query parameters
|
||||
_query_params = []
|
||||
if _params.get('skip') is not None: # noqa: E501
|
||||
_query_params.append(('skip', _params['skip']))
|
||||
|
||||
if _params.get('limit') is not None: # noqa: E501
|
||||
_query_params.append(('limit', _params['limit']))
|
||||
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
# process the form parameters
|
||||
_form_params = []
|
||||
_files = {}
|
||||
# process the body parameter
|
||||
_body_params = None
|
||||
# set the HTTP header `Accept`
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
['application/json']) # noqa: E501
|
||||
|
||||
# authentication setting
|
||||
_auth_settings = [] # noqa: E501
|
||||
|
||||
_response_types_map = {}
|
||||
|
||||
return self.api_client.call_api(
|
||||
'/api/v1/event_messages', 'GET',
|
||||
_path_params,
|
||||
_query_params,
|
||||
_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
response_types_map=_response_types_map,
|
||||
auth_settings=_auth_settings,
|
||||
async_req=_params.get('async_req'),
|
||||
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
|
||||
_preload_content=_params.get('_preload_content', True),
|
||||
_request_timeout=_params.get('_request_timeout'),
|
||||
collection_formats=_collection_formats,
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
192
pkgs/clan-cli/tests/openapi_client/api/repositories_api.py
Normal file
192
pkgs/clan-cli/tests/openapi_client/api/repositories_api.py
Normal file
@@ -0,0 +1,192 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import re # noqa: F401
|
||||
import io
|
||||
import warnings
|
||||
|
||||
from pydantic import validate_arguments, ValidationError
|
||||
|
||||
from pydantic import StrictInt
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
from openapi_client.models.service import Service
|
||||
|
||||
from openapi_client.api_client import ApiClient
|
||||
from openapi_client.api_response import ApiResponse
|
||||
from openapi_client.exceptions import ( # noqa: F401
|
||||
ApiTypeError,
|
||||
ApiValueError
|
||||
)
|
||||
|
||||
|
||||
class RepositoriesApi:
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator
|
||||
Ref: https://openapi-generator.tech
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, api_client=None) -> None:
|
||||
if api_client is None:
|
||||
api_client = ApiClient.get_default()
|
||||
self.api_client = api_client
|
||||
|
||||
@validate_arguments
|
||||
def get_all_repositories(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> List[Service]: # noqa: E501
|
||||
"""Get All Repositories # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_all_repositories(skip, limit, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param skip:
|
||||
:type skip: int
|
||||
:param limit:
|
||||
:type limit: int
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
If one number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: List[Service]
|
||||
"""
|
||||
kwargs['_return_http_data_only'] = True
|
||||
if '_preload_content' in kwargs:
|
||||
message = "Error! Please call the get_all_repositories_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
|
||||
raise ValueError(message)
|
||||
return self.get_all_repositories_with_http_info(skip, limit, **kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def get_all_repositories_with_http_info(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Get All Repositories # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_all_repositories_with_http_info(skip, limit, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param skip:
|
||||
:type skip: int
|
||||
:param limit:
|
||||
:type limit: int
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:type _preload_content: bool, optional
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:type _return_http_data_only: bool, optional
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:type _content_type: string, optional: force content-type for the request
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: tuple(List[Service], status_code(int), headers(HTTPHeaderDict))
|
||||
"""
|
||||
|
||||
_params = locals()
|
||||
|
||||
_all_params = [
|
||||
'skip',
|
||||
'limit'
|
||||
]
|
||||
_all_params.extend(
|
||||
[
|
||||
'async_req',
|
||||
'_return_http_data_only',
|
||||
'_preload_content',
|
||||
'_request_timeout',
|
||||
'_request_auth',
|
||||
'_content_type',
|
||||
'_headers'
|
||||
]
|
||||
)
|
||||
|
||||
# validate the arguments
|
||||
for _key, _val in _params['kwargs'].items():
|
||||
if _key not in _all_params:
|
||||
raise ApiTypeError(
|
||||
"Got an unexpected keyword argument '%s'"
|
||||
" to method get_all_repositories" % _key
|
||||
)
|
||||
_params[_key] = _val
|
||||
del _params['kwargs']
|
||||
|
||||
_collection_formats = {}
|
||||
|
||||
# process the path parameters
|
||||
_path_params = {}
|
||||
|
||||
# process the query parameters
|
||||
_query_params = []
|
||||
if _params.get('skip') is not None: # noqa: E501
|
||||
_query_params.append(('skip', _params['skip']))
|
||||
|
||||
if _params.get('limit') is not None: # noqa: E501
|
||||
_query_params.append(('limit', _params['limit']))
|
||||
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
# process the form parameters
|
||||
_form_params = []
|
||||
_files = {}
|
||||
# process the body parameter
|
||||
_body_params = None
|
||||
# set the HTTP header `Accept`
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
['application/json']) # noqa: E501
|
||||
|
||||
# authentication setting
|
||||
_auth_settings = [] # noqa: E501
|
||||
|
||||
_response_types_map = {
|
||||
'200': "List[Service]",
|
||||
'422': "HTTPValidationError",
|
||||
}
|
||||
|
||||
return self.api_client.call_api(
|
||||
'/api/v1/repositories', 'GET',
|
||||
_path_params,
|
||||
_query_params,
|
||||
_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
response_types_map=_response_types_map,
|
||||
auth_settings=_auth_settings,
|
||||
async_req=_params.get('async_req'),
|
||||
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
|
||||
_preload_content=_params.get('_preload_content', True),
|
||||
_request_timeout=_params.get('_request_timeout'),
|
||||
collection_formats=_collection_formats,
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
192
pkgs/clan-cli/tests/openapi_client/api/resolution_api.py
Normal file
192
pkgs/clan-cli/tests/openapi_client/api/resolution_api.py
Normal file
@@ -0,0 +1,192 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import re # noqa: F401
|
||||
import io
|
||||
import warnings
|
||||
|
||||
from pydantic import validate_arguments, ValidationError
|
||||
|
||||
from pydantic import StrictInt
|
||||
|
||||
from typing import List, Optional
|
||||
|
||||
from openapi_client.models.resolution import Resolution
|
||||
|
||||
from openapi_client.api_client import ApiClient
|
||||
from openapi_client.api_response import ApiResponse
|
||||
from openapi_client.exceptions import ( # noqa: F401
|
||||
ApiTypeError,
|
||||
ApiValueError
|
||||
)
|
||||
|
||||
|
||||
class ResolutionApi:
|
||||
"""NOTE: This class is auto generated by OpenAPI Generator
|
||||
Ref: https://openapi-generator.tech
|
||||
|
||||
Do not edit the class manually.
|
||||
"""
|
||||
|
||||
def __init__(self, api_client=None) -> None:
|
||||
if api_client is None:
|
||||
api_client = ApiClient.get_default()
|
||||
self.api_client = api_client
|
||||
|
||||
@validate_arguments
|
||||
def get_all_resolutions(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> List[Resolution]: # noqa: E501
|
||||
"""Get All Resolutions # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_all_resolutions(skip, limit, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param skip:
|
||||
:type skip: int
|
||||
:param limit:
|
||||
:type limit: int
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _request_timeout: timeout setting for this request.
|
||||
If one number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: List[Resolution]
|
||||
"""
|
||||
kwargs['_return_http_data_only'] = True
|
||||
if '_preload_content' in kwargs:
|
||||
message = "Error! Please call the get_all_resolutions_with_http_info method with `_preload_content` instead and obtain raw data from ApiResponse.raw_data" # noqa: E501
|
||||
raise ValueError(message)
|
||||
return self.get_all_resolutions_with_http_info(skip, limit, **kwargs) # noqa: E501
|
||||
|
||||
@validate_arguments
|
||||
def get_all_resolutions_with_http_info(self, skip : Optional[StrictInt] = None, limit : Optional[StrictInt] = None, **kwargs) -> ApiResponse: # noqa: E501
|
||||
"""Get All Resolutions # noqa: E501
|
||||
|
||||
This method makes a synchronous HTTP request by default. To make an
|
||||
asynchronous HTTP request, please pass async_req=True
|
||||
|
||||
>>> thread = api.get_all_resolutions_with_http_info(skip, limit, async_req=True)
|
||||
>>> result = thread.get()
|
||||
|
||||
:param skip:
|
||||
:type skip: int
|
||||
:param limit:
|
||||
:type limit: int
|
||||
:param async_req: Whether to execute the request asynchronously.
|
||||
:type async_req: bool, optional
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:type _preload_content: bool, optional
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:type _return_http_data_only: bool, optional
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_auth: dict, optional
|
||||
:type _content_type: string, optional: force content-type for the request
|
||||
:return: Returns the result object.
|
||||
If the method is called asynchronously,
|
||||
returns the request thread.
|
||||
:rtype: tuple(List[Resolution], status_code(int), headers(HTTPHeaderDict))
|
||||
"""
|
||||
|
||||
_params = locals()
|
||||
|
||||
_all_params = [
|
||||
'skip',
|
||||
'limit'
|
||||
]
|
||||
_all_params.extend(
|
||||
[
|
||||
'async_req',
|
||||
'_return_http_data_only',
|
||||
'_preload_content',
|
||||
'_request_timeout',
|
||||
'_request_auth',
|
||||
'_content_type',
|
||||
'_headers'
|
||||
]
|
||||
)
|
||||
|
||||
# validate the arguments
|
||||
for _key, _val in _params['kwargs'].items():
|
||||
if _key not in _all_params:
|
||||
raise ApiTypeError(
|
||||
"Got an unexpected keyword argument '%s'"
|
||||
" to method get_all_resolutions" % _key
|
||||
)
|
||||
_params[_key] = _val
|
||||
del _params['kwargs']
|
||||
|
||||
_collection_formats = {}
|
||||
|
||||
# process the path parameters
|
||||
_path_params = {}
|
||||
|
||||
# process the query parameters
|
||||
_query_params = []
|
||||
if _params.get('skip') is not None: # noqa: E501
|
||||
_query_params.append(('skip', _params['skip']))
|
||||
|
||||
if _params.get('limit') is not None: # noqa: E501
|
||||
_query_params.append(('limit', _params['limit']))
|
||||
|
||||
# process the header parameters
|
||||
_header_params = dict(_params.get('_headers', {}))
|
||||
# process the form parameters
|
||||
_form_params = []
|
||||
_files = {}
|
||||
# process the body parameter
|
||||
_body_params = None
|
||||
# set the HTTP header `Accept`
|
||||
_header_params['Accept'] = self.api_client.select_header_accept(
|
||||
['application/json']) # noqa: E501
|
||||
|
||||
# authentication setting
|
||||
_auth_settings = [] # noqa: E501
|
||||
|
||||
_response_types_map = {
|
||||
'200': "List[Resolution]",
|
||||
'422': "HTTPValidationError",
|
||||
}
|
||||
|
||||
return self.api_client.call_api(
|
||||
'/api/v1/resolutions', 'GET',
|
||||
_path_params,
|
||||
_query_params,
|
||||
_header_params,
|
||||
body=_body_params,
|
||||
post_params=_form_params,
|
||||
files=_files,
|
||||
response_types_map=_response_types_map,
|
||||
auth_settings=_auth_settings,
|
||||
async_req=_params.get('async_req'),
|
||||
_return_http_data_only=_params.get('_return_http_data_only'), # noqa: E501
|
||||
_preload_content=_params.get('_preload_content', True),
|
||||
_request_timeout=_params.get('_request_timeout'),
|
||||
collection_formats=_collection_formats,
|
||||
_request_auth=_params.get('_request_auth'))
|
||||
1414
pkgs/clan-cli/tests/openapi_client/api/services_api.py
Normal file
1414
pkgs/clan-cli/tests/openapi_client/api/services_api.py
Normal file
File diff suppressed because it is too large
Load Diff
758
pkgs/clan-cli/tests/openapi_client/api_client.py
Normal file
758
pkgs/clan-cli/tests/openapi_client/api_client.py
Normal file
@@ -0,0 +1,758 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import atexit
|
||||
import datetime
|
||||
from dateutil.parser import parse
|
||||
import json
|
||||
import mimetypes
|
||||
from multiprocessing.pool import ThreadPool
|
||||
import os
|
||||
import re
|
||||
import tempfile
|
||||
|
||||
from urllib.parse import quote
|
||||
|
||||
from openapi_client.configuration import Configuration
|
||||
from openapi_client.api_response import ApiResponse
|
||||
import openapi_client.models
|
||||
from openapi_client import rest
|
||||
from openapi_client.exceptions import ApiValueError, ApiException
|
||||
|
||||
|
||||
class ApiClient:
|
||||
"""Generic API client for OpenAPI client library builds.
|
||||
|
||||
OpenAPI generic API client. This client handles the client-
|
||||
server communication, and is invariant across implementations. Specifics of
|
||||
the methods and models for each application are generated from the OpenAPI
|
||||
templates.
|
||||
|
||||
:param configuration: .Configuration object for this client
|
||||
:param header_name: a header to pass when making calls to the API.
|
||||
:param header_value: a header value to pass when making calls to
|
||||
the API.
|
||||
:param cookie: a cookie to include in the header when making calls
|
||||
to the API
|
||||
:param pool_threads: The number of threads to use for async requests
|
||||
to the API. More threads means more concurrent API requests.
|
||||
"""
|
||||
|
||||
PRIMITIVE_TYPES = (float, bool, bytes, str, int)
|
||||
NATIVE_TYPES_MAPPING = {
|
||||
'int': int,
|
||||
'long': int, # TODO remove as only py3 is supported?
|
||||
'float': float,
|
||||
'str': str,
|
||||
'bool': bool,
|
||||
'date': datetime.date,
|
||||
'datetime': datetime.datetime,
|
||||
'object': object,
|
||||
}
|
||||
_pool = None
|
||||
|
||||
def __init__(self, configuration=None, header_name=None, header_value=None,
|
||||
cookie=None, pool_threads=1) -> None:
|
||||
# use default configuration if none is provided
|
||||
if configuration is None:
|
||||
configuration = Configuration.get_default()
|
||||
self.configuration = configuration
|
||||
self.pool_threads = pool_threads
|
||||
|
||||
self.rest_client = rest.RESTClientObject(configuration)
|
||||
self.default_headers = {}
|
||||
if header_name is not None:
|
||||
self.default_headers[header_name] = header_value
|
||||
self.cookie = cookie
|
||||
# Set default User-Agent.
|
||||
self.user_agent = 'OpenAPI-Generator/1.0.0/python'
|
||||
self.client_side_validation = configuration.client_side_validation
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_value, traceback):
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
if self._pool:
|
||||
self._pool.close()
|
||||
self._pool.join()
|
||||
self._pool = None
|
||||
if hasattr(atexit, 'unregister'):
|
||||
atexit.unregister(self.close)
|
||||
|
||||
@property
|
||||
def pool(self):
|
||||
"""Create thread pool on first request
|
||||
avoids instantiating unused threadpool for blocking clients.
|
||||
"""
|
||||
if self._pool is None:
|
||||
atexit.register(self.close)
|
||||
self._pool = ThreadPool(self.pool_threads)
|
||||
return self._pool
|
||||
|
||||
@property
|
||||
def user_agent(self):
|
||||
"""User agent for this API client"""
|
||||
return self.default_headers['User-Agent']
|
||||
|
||||
@user_agent.setter
|
||||
def user_agent(self, value):
|
||||
self.default_headers['User-Agent'] = value
|
||||
|
||||
def set_default_header(self, header_name, header_value):
|
||||
self.default_headers[header_name] = header_value
|
||||
|
||||
|
||||
_default = None
|
||||
|
||||
@classmethod
|
||||
def get_default(cls):
|
||||
"""Return new instance of ApiClient.
|
||||
|
||||
This method returns newly created, based on default constructor,
|
||||
object of ApiClient class or returns a copy of default
|
||||
ApiClient.
|
||||
|
||||
:return: The ApiClient object.
|
||||
"""
|
||||
if cls._default is None:
|
||||
cls._default = ApiClient()
|
||||
return cls._default
|
||||
|
||||
@classmethod
|
||||
def set_default(cls, default):
|
||||
"""Set default instance of ApiClient.
|
||||
|
||||
It stores default ApiClient.
|
||||
|
||||
:param default: object of ApiClient.
|
||||
"""
|
||||
cls._default = default
|
||||
|
||||
def __call_api(
|
||||
self, resource_path, method, path_params=None,
|
||||
query_params=None, header_params=None, body=None, post_params=None,
|
||||
files=None, response_types_map=None, auth_settings=None,
|
||||
_return_http_data_only=None, collection_formats=None,
|
||||
_preload_content=True, _request_timeout=None, _host=None,
|
||||
_request_auth=None):
|
||||
|
||||
config = self.configuration
|
||||
|
||||
# header parameters
|
||||
header_params = header_params or {}
|
||||
header_params.update(self.default_headers)
|
||||
if self.cookie:
|
||||
header_params['Cookie'] = self.cookie
|
||||
if header_params:
|
||||
header_params = self.sanitize_for_serialization(header_params)
|
||||
header_params = dict(self.parameters_to_tuples(header_params,
|
||||
collection_formats))
|
||||
|
||||
# path parameters
|
||||
if path_params:
|
||||
path_params = self.sanitize_for_serialization(path_params)
|
||||
path_params = self.parameters_to_tuples(path_params,
|
||||
collection_formats)
|
||||
for k, v in path_params:
|
||||
# specified safe chars, encode everything
|
||||
resource_path = resource_path.replace(
|
||||
'{%s}' % k,
|
||||
quote(str(v), safe=config.safe_chars_for_path_param)
|
||||
)
|
||||
|
||||
# post parameters
|
||||
if post_params or files:
|
||||
post_params = post_params if post_params else []
|
||||
post_params = self.sanitize_for_serialization(post_params)
|
||||
post_params = self.parameters_to_tuples(post_params,
|
||||
collection_formats)
|
||||
post_params.extend(self.files_parameters(files))
|
||||
|
||||
# auth setting
|
||||
self.update_params_for_auth(
|
||||
header_params, query_params, auth_settings,
|
||||
resource_path, method, body,
|
||||
request_auth=_request_auth)
|
||||
|
||||
# body
|
||||
if body:
|
||||
body = self.sanitize_for_serialization(body)
|
||||
|
||||
# request url
|
||||
if _host is None:
|
||||
url = self.configuration.host + resource_path
|
||||
else:
|
||||
# use server/host defined in path or operation instead
|
||||
url = _host + resource_path
|
||||
|
||||
# query parameters
|
||||
if query_params:
|
||||
query_params = self.sanitize_for_serialization(query_params)
|
||||
url_query = self.parameters_to_url_query(query_params,
|
||||
collection_formats)
|
||||
url += "?" + url_query
|
||||
|
||||
try:
|
||||
# perform request and return response
|
||||
response_data = self.request(
|
||||
method, url,
|
||||
query_params=query_params,
|
||||
headers=header_params,
|
||||
post_params=post_params, body=body,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout)
|
||||
except ApiException as e:
|
||||
if e.body:
|
||||
e.body = e.body.decode('utf-8')
|
||||
raise e
|
||||
|
||||
self.last_response = response_data
|
||||
|
||||
return_data = None # assuming derialization is not needed
|
||||
# data needs deserialization or returns HTTP data (deserialized) only
|
||||
if _preload_content or _return_http_data_only:
|
||||
response_type = response_types_map.get(str(response_data.status), None)
|
||||
if not response_type and isinstance(response_data.status, int) and 100 <= response_data.status <= 599:
|
||||
# if not found, look for '1XX', '2XX', etc.
|
||||
response_type = response_types_map.get(str(response_data.status)[0] + "XX", None)
|
||||
|
||||
if response_type == "bytearray":
|
||||
response_data.data = response_data.data
|
||||
else:
|
||||
match = None
|
||||
content_type = response_data.getheader('content-type')
|
||||
if content_type is not None:
|
||||
match = re.search(r"charset=([a-zA-Z\-\d]+)[\s;]?", content_type)
|
||||
encoding = match.group(1) if match else "utf-8"
|
||||
response_data.data = response_data.data.decode(encoding)
|
||||
|
||||
# deserialize response data
|
||||
if response_type == "bytearray":
|
||||
return_data = response_data.data
|
||||
elif response_type:
|
||||
return_data = self.deserialize(response_data, response_type)
|
||||
else:
|
||||
return_data = None
|
||||
|
||||
if _return_http_data_only:
|
||||
return return_data
|
||||
else:
|
||||
return ApiResponse(status_code = response_data.status,
|
||||
data = return_data,
|
||||
headers = response_data.getheaders(),
|
||||
raw_data = response_data.data)
|
||||
|
||||
def sanitize_for_serialization(self, obj):
|
||||
"""Builds a JSON POST object.
|
||||
|
||||
If obj is None, return None.
|
||||
If obj is str, int, long, float, bool, return directly.
|
||||
If obj is datetime.datetime, datetime.date
|
||||
convert to string in iso8601 format.
|
||||
If obj is list, sanitize each element in the list.
|
||||
If obj is dict, return the dict.
|
||||
If obj is OpenAPI model, return the properties dict.
|
||||
|
||||
:param obj: The data to serialize.
|
||||
:return: The serialized form of data.
|
||||
"""
|
||||
if obj is None:
|
||||
return None
|
||||
elif isinstance(obj, self.PRIMITIVE_TYPES):
|
||||
return obj
|
||||
elif isinstance(obj, list):
|
||||
return [self.sanitize_for_serialization(sub_obj)
|
||||
for sub_obj in obj]
|
||||
elif isinstance(obj, tuple):
|
||||
return tuple(self.sanitize_for_serialization(sub_obj)
|
||||
for sub_obj in obj)
|
||||
elif isinstance(obj, (datetime.datetime, datetime.date)):
|
||||
return obj.isoformat()
|
||||
|
||||
if isinstance(obj, dict):
|
||||
obj_dict = obj
|
||||
else:
|
||||
# Convert model obj to dict except
|
||||
# attributes `openapi_types`, `attribute_map`
|
||||
# and attributes which value is not None.
|
||||
# Convert attribute name to json key in
|
||||
# model definition for request.
|
||||
obj_dict = obj.to_dict()
|
||||
|
||||
return {key: self.sanitize_for_serialization(val)
|
||||
for key, val in obj_dict.items()}
|
||||
|
||||
def deserialize(self, response, response_type):
|
||||
"""Deserializes response into an object.
|
||||
|
||||
:param response: RESTResponse object to be deserialized.
|
||||
:param response_type: class literal for
|
||||
deserialized object, or string of class name.
|
||||
|
||||
:return: deserialized object.
|
||||
"""
|
||||
# handle file downloading
|
||||
# save response body into a tmp file and return the instance
|
||||
if response_type == "file":
|
||||
return self.__deserialize_file(response)
|
||||
|
||||
# fetch data from response object
|
||||
try:
|
||||
data = json.loads(response.data)
|
||||
except ValueError:
|
||||
data = response.data
|
||||
|
||||
return self.__deserialize(data, response_type)
|
||||
|
||||
def __deserialize(self, data, klass):
|
||||
"""Deserializes dict, list, str into an object.
|
||||
|
||||
:param data: dict, list or str.
|
||||
:param klass: class literal, or string of class name.
|
||||
|
||||
:return: object.
|
||||
"""
|
||||
if data is None:
|
||||
return None
|
||||
|
||||
if isinstance(klass, str):
|
||||
if klass.startswith('List['):
|
||||
sub_kls = re.match(r'List\[(.*)]', klass).group(1)
|
||||
return [self.__deserialize(sub_data, sub_kls)
|
||||
for sub_data in data]
|
||||
|
||||
if klass.startswith('Dict['):
|
||||
sub_kls = re.match(r'Dict\[([^,]*), (.*)]', klass).group(2)
|
||||
return {k: self.__deserialize(v, sub_kls)
|
||||
for k, v in data.items()}
|
||||
|
||||
# convert str to class
|
||||
if klass in self.NATIVE_TYPES_MAPPING:
|
||||
klass = self.NATIVE_TYPES_MAPPING[klass]
|
||||
else:
|
||||
klass = getattr(openapi_client.models, klass)
|
||||
|
||||
if klass in self.PRIMITIVE_TYPES:
|
||||
return self.__deserialize_primitive(data, klass)
|
||||
elif klass == object:
|
||||
return self.__deserialize_object(data)
|
||||
elif klass == datetime.date:
|
||||
return self.__deserialize_date(data)
|
||||
elif klass == datetime.datetime:
|
||||
return self.__deserialize_datetime(data)
|
||||
else:
|
||||
return self.__deserialize_model(data, klass)
|
||||
|
||||
def call_api(self, resource_path, method,
|
||||
path_params=None, query_params=None, header_params=None,
|
||||
body=None, post_params=None, files=None,
|
||||
response_types_map=None, auth_settings=None,
|
||||
async_req=None, _return_http_data_only=None,
|
||||
collection_formats=None, _preload_content=True,
|
||||
_request_timeout=None, _host=None, _request_auth=None):
|
||||
"""Makes the HTTP request (synchronous) and returns deserialized data.
|
||||
|
||||
To make an async_req request, set the async_req parameter.
|
||||
|
||||
:param resource_path: Path to method endpoint.
|
||||
:param method: Method to call.
|
||||
:param path_params: Path parameters in the url.
|
||||
:param query_params: Query parameters in the url.
|
||||
:param header_params: Header parameters to be
|
||||
placed in the request header.
|
||||
:param body: Request body.
|
||||
:param post_params dict: Request post form parameters,
|
||||
for `application/x-www-form-urlencoded`, `multipart/form-data`.
|
||||
:param auth_settings list: Auth Settings names for the request.
|
||||
:param response: Response data type.
|
||||
:param files dict: key -> filename, value -> filepath,
|
||||
for `multipart/form-data`.
|
||||
:param async_req bool: execute request asynchronously
|
||||
:param _return_http_data_only: response data instead of ApiResponse
|
||||
object with status code, headers, etc
|
||||
:param _preload_content: if False, the ApiResponse.data will
|
||||
be set to none and raw_data will store the
|
||||
HTTP response body without reading/decoding.
|
||||
Default is True.
|
||||
:param collection_formats: dict of collection formats for path, query,
|
||||
header, and post parameters.
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
:param _request_auth: set to override the auth_settings for an a single
|
||||
request; this effectively ignores the authentication
|
||||
in the spec for a single request.
|
||||
:type _request_token: dict, optional
|
||||
:return:
|
||||
If async_req parameter is True,
|
||||
the request will be called asynchronously.
|
||||
The method will return the request thread.
|
||||
If parameter async_req is False or missing,
|
||||
then the method will return the response directly.
|
||||
"""
|
||||
if not async_req:
|
||||
return self.__call_api(resource_path, method,
|
||||
path_params, query_params, header_params,
|
||||
body, post_params, files,
|
||||
response_types_map, auth_settings,
|
||||
_return_http_data_only, collection_formats,
|
||||
_preload_content, _request_timeout, _host,
|
||||
_request_auth)
|
||||
|
||||
return self.pool.apply_async(self.__call_api, (resource_path,
|
||||
method, path_params,
|
||||
query_params,
|
||||
header_params, body,
|
||||
post_params, files,
|
||||
response_types_map,
|
||||
auth_settings,
|
||||
_return_http_data_only,
|
||||
collection_formats,
|
||||
_preload_content,
|
||||
_request_timeout,
|
||||
_host, _request_auth))
|
||||
|
||||
def request(self, method, url, query_params=None, headers=None,
|
||||
post_params=None, body=None, _preload_content=True,
|
||||
_request_timeout=None):
|
||||
"""Makes the HTTP request using RESTClient."""
|
||||
if method == "GET":
|
||||
return self.rest_client.get_request(url,
|
||||
query_params=query_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
headers=headers)
|
||||
elif method == "HEAD":
|
||||
return self.rest_client.head_request(url,
|
||||
query_params=query_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
headers=headers)
|
||||
elif method == "OPTIONS":
|
||||
return self.rest_client.options_request(url,
|
||||
query_params=query_params,
|
||||
headers=headers,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout)
|
||||
elif method == "POST":
|
||||
return self.rest_client.post_request(url,
|
||||
query_params=query_params,
|
||||
headers=headers,
|
||||
post_params=post_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
elif method == "PUT":
|
||||
return self.rest_client.put_request(url,
|
||||
query_params=query_params,
|
||||
headers=headers,
|
||||
post_params=post_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
elif method == "PATCH":
|
||||
return self.rest_client.patch_request(url,
|
||||
query_params=query_params,
|
||||
headers=headers,
|
||||
post_params=post_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
elif method == "DELETE":
|
||||
return self.rest_client.delete_request(url,
|
||||
query_params=query_params,
|
||||
headers=headers,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
else:
|
||||
raise ApiValueError(
|
||||
"http method must be `GET`, `HEAD`, `OPTIONS`,"
|
||||
" `POST`, `PATCH`, `PUT` or `DELETE`."
|
||||
)
|
||||
|
||||
def parameters_to_tuples(self, params, collection_formats):
|
||||
"""Get parameters as list of tuples, formatting collections.
|
||||
|
||||
:param params: Parameters as dict or list of two-tuples
|
||||
:param dict collection_formats: Parameter collection formats
|
||||
:return: Parameters as list of tuples, collections formatted
|
||||
"""
|
||||
new_params = []
|
||||
if collection_formats is None:
|
||||
collection_formats = {}
|
||||
for k, v in params.items() if isinstance(params, dict) else params: # noqa: E501
|
||||
if k in collection_formats:
|
||||
collection_format = collection_formats[k]
|
||||
if collection_format == 'multi':
|
||||
new_params.extend((k, value) for value in v)
|
||||
else:
|
||||
if collection_format == 'ssv':
|
||||
delimiter = ' '
|
||||
elif collection_format == 'tsv':
|
||||
delimiter = '\t'
|
||||
elif collection_format == 'pipes':
|
||||
delimiter = '|'
|
||||
else: # csv is the default
|
||||
delimiter = ','
|
||||
new_params.append(
|
||||
(k, delimiter.join(str(value) for value in v)))
|
||||
else:
|
||||
new_params.append((k, v))
|
||||
return new_params
|
||||
|
||||
def parameters_to_url_query(self, params, collection_formats):
|
||||
"""Get parameters as list of tuples, formatting collections.
|
||||
|
||||
:param params: Parameters as dict or list of two-tuples
|
||||
:param dict collection_formats: Parameter collection formats
|
||||
:return: URL query string (e.g. a=Hello%20World&b=123)
|
||||
"""
|
||||
new_params = []
|
||||
if collection_formats is None:
|
||||
collection_formats = {}
|
||||
for k, v in params.items() if isinstance(params, dict) else params: # noqa: E501
|
||||
if isinstance(v, (int, float)):
|
||||
v = str(v)
|
||||
if isinstance(v, bool):
|
||||
v = str(v).lower()
|
||||
if isinstance(v, dict):
|
||||
v = json.dumps(v)
|
||||
|
||||
if k in collection_formats:
|
||||
collection_format = collection_formats[k]
|
||||
if collection_format == 'multi':
|
||||
new_params.extend((k, value) for value in v)
|
||||
else:
|
||||
if collection_format == 'ssv':
|
||||
delimiter = ' '
|
||||
elif collection_format == 'tsv':
|
||||
delimiter = '\t'
|
||||
elif collection_format == 'pipes':
|
||||
delimiter = '|'
|
||||
else: # csv is the default
|
||||
delimiter = ','
|
||||
new_params.append(
|
||||
(k, delimiter.join(quote(str(value)) for value in v)))
|
||||
else:
|
||||
new_params.append((k, quote(str(v))))
|
||||
|
||||
return "&".join(["=".join(item) for item in new_params])
|
||||
|
||||
def files_parameters(self, files=None):
|
||||
"""Builds form parameters.
|
||||
|
||||
:param files: File parameters.
|
||||
:return: Form parameters with files.
|
||||
"""
|
||||
params = []
|
||||
|
||||
if files:
|
||||
for k, v in files.items():
|
||||
if not v:
|
||||
continue
|
||||
file_names = v if type(v) is list else [v]
|
||||
for n in file_names:
|
||||
with open(n, 'rb') as f:
|
||||
filename = os.path.basename(f.name)
|
||||
filedata = f.read()
|
||||
mimetype = (mimetypes.guess_type(filename)[0] or
|
||||
'application/octet-stream')
|
||||
params.append(
|
||||
tuple([k, tuple([filename, filedata, mimetype])]))
|
||||
|
||||
return params
|
||||
|
||||
def select_header_accept(self, accepts):
|
||||
"""Returns `Accept` based on an array of accepts provided.
|
||||
|
||||
:param accepts: List of headers.
|
||||
:return: Accept (e.g. application/json).
|
||||
"""
|
||||
if not accepts:
|
||||
return
|
||||
|
||||
for accept in accepts:
|
||||
if re.search('json', accept, re.IGNORECASE):
|
||||
return accept
|
||||
|
||||
return accepts[0]
|
||||
|
||||
def select_header_content_type(self, content_types):
|
||||
"""Returns `Content-Type` based on an array of content_types provided.
|
||||
|
||||
:param content_types: List of content-types.
|
||||
:return: Content-Type (e.g. application/json).
|
||||
"""
|
||||
if not content_types:
|
||||
return None
|
||||
|
||||
for content_type in content_types:
|
||||
if re.search('json', content_type, re.IGNORECASE):
|
||||
return content_type
|
||||
|
||||
return content_types[0]
|
||||
|
||||
def update_params_for_auth(self, headers, queries, auth_settings,
|
||||
resource_path, method, body,
|
||||
request_auth=None):
|
||||
"""Updates header and query params based on authentication setting.
|
||||
|
||||
:param headers: Header parameters dict to be updated.
|
||||
:param queries: Query parameters tuple list to be updated.
|
||||
:param auth_settings: Authentication setting identifiers list.
|
||||
:resource_path: A string representation of the HTTP request resource path.
|
||||
:method: A string representation of the HTTP request method.
|
||||
:body: A object representing the body of the HTTP request.
|
||||
The object type is the return value of sanitize_for_serialization().
|
||||
:param request_auth: if set, the provided settings will
|
||||
override the token in the configuration.
|
||||
"""
|
||||
if not auth_settings:
|
||||
return
|
||||
|
||||
if request_auth:
|
||||
self._apply_auth_params(headers, queries,
|
||||
resource_path, method, body,
|
||||
request_auth)
|
||||
return
|
||||
|
||||
for auth in auth_settings:
|
||||
auth_setting = self.configuration.auth_settings().get(auth)
|
||||
if auth_setting:
|
||||
self._apply_auth_params(headers, queries,
|
||||
resource_path, method, body,
|
||||
auth_setting)
|
||||
|
||||
def _apply_auth_params(self, headers, queries,
|
||||
resource_path, method, body,
|
||||
auth_setting):
|
||||
"""Updates the request parameters based on a single auth_setting
|
||||
|
||||
:param headers: Header parameters dict to be updated.
|
||||
:param queries: Query parameters tuple list to be updated.
|
||||
:resource_path: A string representation of the HTTP request resource path.
|
||||
:method: A string representation of the HTTP request method.
|
||||
:body: A object representing the body of the HTTP request.
|
||||
The object type is the return value of sanitize_for_serialization().
|
||||
:param auth_setting: auth settings for the endpoint
|
||||
"""
|
||||
if auth_setting['in'] == 'cookie':
|
||||
headers['Cookie'] = auth_setting['value']
|
||||
elif auth_setting['in'] == 'header':
|
||||
if auth_setting['type'] != 'http-signature':
|
||||
headers[auth_setting['key']] = auth_setting['value']
|
||||
elif auth_setting['in'] == 'query':
|
||||
queries.append((auth_setting['key'], auth_setting['value']))
|
||||
else:
|
||||
raise ApiValueError(
|
||||
'Authentication token must be in `query` or `header`'
|
||||
)
|
||||
|
||||
def __deserialize_file(self, response):
|
||||
"""Deserializes body to file
|
||||
|
||||
Saves response body into a file in a temporary folder,
|
||||
using the filename from the `Content-Disposition` header if provided.
|
||||
|
||||
:param response: RESTResponse.
|
||||
:return: file path.
|
||||
"""
|
||||
fd, path = tempfile.mkstemp(dir=self.configuration.temp_folder_path)
|
||||
os.close(fd)
|
||||
os.remove(path)
|
||||
|
||||
content_disposition = response.getheader("Content-Disposition")
|
||||
if content_disposition:
|
||||
filename = re.search(r'filename=[\'"]?([^\'"\s]+)[\'"]?',
|
||||
content_disposition).group(1)
|
||||
path = os.path.join(os.path.dirname(path), filename)
|
||||
|
||||
with open(path, "wb") as f:
|
||||
f.write(response.data)
|
||||
|
||||
return path
|
||||
|
||||
def __deserialize_primitive(self, data, klass):
|
||||
"""Deserializes string to primitive type.
|
||||
|
||||
:param data: str.
|
||||
:param klass: class literal.
|
||||
|
||||
:return: int, long, float, str, bool.
|
||||
"""
|
||||
try:
|
||||
return klass(data)
|
||||
except UnicodeEncodeError:
|
||||
return str(data)
|
||||
except TypeError:
|
||||
return data
|
||||
|
||||
def __deserialize_object(self, value):
|
||||
"""Return an original value.
|
||||
|
||||
:return: object.
|
||||
"""
|
||||
return value
|
||||
|
||||
def __deserialize_date(self, string):
|
||||
"""Deserializes string to date.
|
||||
|
||||
:param string: str.
|
||||
:return: date.
|
||||
"""
|
||||
try:
|
||||
return parse(string).date()
|
||||
except ImportError:
|
||||
return string
|
||||
except ValueError:
|
||||
raise rest.ApiException(
|
||||
status=0,
|
||||
reason="Failed to parse `{0}` as date object".format(string)
|
||||
)
|
||||
|
||||
def __deserialize_datetime(self, string):
|
||||
"""Deserializes string to datetime.
|
||||
|
||||
The string should be in iso8601 datetime format.
|
||||
|
||||
:param string: str.
|
||||
:return: datetime.
|
||||
"""
|
||||
try:
|
||||
return parse(string)
|
||||
except ImportError:
|
||||
return string
|
||||
except ValueError:
|
||||
raise rest.ApiException(
|
||||
status=0,
|
||||
reason=(
|
||||
"Failed to parse `{0}` as datetime object"
|
||||
.format(string)
|
||||
)
|
||||
)
|
||||
|
||||
def __deserialize_model(self, data, klass):
|
||||
"""Deserializes list or dict to model.
|
||||
|
||||
:param data: dict, list.
|
||||
:param klass: class literal.
|
||||
:return: model object.
|
||||
"""
|
||||
|
||||
return klass.from_dict(data)
|
||||
25
pkgs/clan-cli/tests/openapi_client/api_response.py
Normal file
25
pkgs/clan-cli/tests/openapi_client/api_response.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""API response object."""
|
||||
|
||||
from __future__ import annotations
|
||||
from typing import Any, Dict, Optional
|
||||
from pydantic import Field, StrictInt, StrictStr
|
||||
|
||||
class ApiResponse:
|
||||
"""
|
||||
API response object
|
||||
"""
|
||||
|
||||
status_code: Optional[StrictInt] = Field(None, description="HTTP status code")
|
||||
headers: Optional[Dict[StrictStr, StrictStr]] = Field(None, description="HTTP headers")
|
||||
data: Optional[Any] = Field(None, description="Deserialized data given the data type")
|
||||
raw_data: Optional[Any] = Field(None, description="Raw data (HTTP response body)")
|
||||
|
||||
def __init__(self,
|
||||
status_code=None,
|
||||
headers=None,
|
||||
data=None,
|
||||
raw_data=None) -> None:
|
||||
self.status_code = status_code
|
||||
self.headers = headers
|
||||
self.data = data
|
||||
self.raw_data = raw_data
|
||||
434
pkgs/clan-cli/tests/openapi_client/configuration.py
Normal file
434
pkgs/clan-cli/tests/openapi_client/configuration.py
Normal file
@@ -0,0 +1,434 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import copy
|
||||
import logging
|
||||
import multiprocessing
|
||||
import sys
|
||||
import urllib3
|
||||
|
||||
import http.client as httplib
|
||||
|
||||
JSON_SCHEMA_VALIDATION_KEYWORDS = {
|
||||
'multipleOf', 'maximum', 'exclusiveMaximum',
|
||||
'minimum', 'exclusiveMinimum', 'maxLength',
|
||||
'minLength', 'pattern', 'maxItems', 'minItems'
|
||||
}
|
||||
|
||||
class Configuration:
|
||||
"""This class contains various settings of the API client.
|
||||
|
||||
:param host: Base url.
|
||||
:param api_key: Dict to store API key(s).
|
||||
Each entry in the dict specifies an API key.
|
||||
The dict key is the name of the security scheme in the OAS specification.
|
||||
The dict value is the API key secret.
|
||||
:param api_key_prefix: Dict to store API prefix (e.g. Bearer).
|
||||
The dict key is the name of the security scheme in the OAS specification.
|
||||
The dict value is an API key prefix when generating the auth data.
|
||||
:param username: Username for HTTP basic authentication.
|
||||
:param password: Password for HTTP basic authentication.
|
||||
:param access_token: Access token.
|
||||
:param server_index: Index to servers configuration.
|
||||
:param server_variables: Mapping with string values to replace variables in
|
||||
templated server configuration. The validation of enums is performed for
|
||||
variables with defined enum values before.
|
||||
:param server_operation_index: Mapping from operation ID to an index to server
|
||||
configuration.
|
||||
:param server_operation_variables: Mapping from operation ID to a mapping with
|
||||
string values to replace variables in templated server configuration.
|
||||
The validation of enums is performed for variables with defined enum
|
||||
values before.
|
||||
:param ssl_ca_cert: str - the path to a file of concatenated CA certificates
|
||||
in PEM format.
|
||||
|
||||
"""
|
||||
|
||||
_default = None
|
||||
|
||||
def __init__(self, host=None,
|
||||
api_key=None, api_key_prefix=None,
|
||||
username=None, password=None,
|
||||
access_token=None,
|
||||
server_index=None, server_variables=None,
|
||||
server_operation_index=None, server_operation_variables=None,
|
||||
ssl_ca_cert=None,
|
||||
) -> None:
|
||||
"""Constructor
|
||||
"""
|
||||
self._base_path = "http://localhost" if host is None else host
|
||||
"""Default Base url
|
||||
"""
|
||||
self.server_index = 0 if server_index is None and host is None else server_index
|
||||
self.server_operation_index = server_operation_index or {}
|
||||
"""Default server index
|
||||
"""
|
||||
self.server_variables = server_variables or {}
|
||||
self.server_operation_variables = server_operation_variables or {}
|
||||
"""Default server variables
|
||||
"""
|
||||
self.temp_folder_path = None
|
||||
"""Temp file folder for downloading files
|
||||
"""
|
||||
# Authentication Settings
|
||||
self.api_key = {}
|
||||
if api_key:
|
||||
self.api_key = api_key
|
||||
"""dict to store API key(s)
|
||||
"""
|
||||
self.api_key_prefix = {}
|
||||
if api_key_prefix:
|
||||
self.api_key_prefix = api_key_prefix
|
||||
"""dict to store API prefix (e.g. Bearer)
|
||||
"""
|
||||
self.refresh_api_key_hook = None
|
||||
"""function hook to refresh API key if expired
|
||||
"""
|
||||
self.username = username
|
||||
"""Username for HTTP basic authentication
|
||||
"""
|
||||
self.password = password
|
||||
"""Password for HTTP basic authentication
|
||||
"""
|
||||
self.access_token = access_token
|
||||
"""Access token
|
||||
"""
|
||||
self.logger = {}
|
||||
"""Logging Settings
|
||||
"""
|
||||
self.logger["package_logger"] = logging.getLogger("openapi_client")
|
||||
self.logger["urllib3_logger"] = logging.getLogger("urllib3")
|
||||
self.logger_format = '%(asctime)s %(levelname)s %(message)s'
|
||||
"""Log format
|
||||
"""
|
||||
self.logger_stream_handler = None
|
||||
"""Log stream handler
|
||||
"""
|
||||
self.logger_file_handler = None
|
||||
"""Log file handler
|
||||
"""
|
||||
self.logger_file = None
|
||||
"""Debug file location
|
||||
"""
|
||||
self.debug = False
|
||||
"""Debug switch
|
||||
"""
|
||||
|
||||
self.verify_ssl = True
|
||||
"""SSL/TLS verification
|
||||
Set this to false to skip verifying SSL certificate when calling API
|
||||
from https server.
|
||||
"""
|
||||
self.ssl_ca_cert = ssl_ca_cert
|
||||
"""Set this to customize the certificate file to verify the peer.
|
||||
"""
|
||||
self.cert_file = None
|
||||
"""client certificate file
|
||||
"""
|
||||
self.key_file = None
|
||||
"""client key file
|
||||
"""
|
||||
self.assert_hostname = None
|
||||
"""Set this to True/False to enable/disable SSL hostname verification.
|
||||
"""
|
||||
self.tls_server_name = None
|
||||
"""SSL/TLS Server Name Indication (SNI)
|
||||
Set this to the SNI value expected by the server.
|
||||
"""
|
||||
|
||||
self.connection_pool_maxsize = multiprocessing.cpu_count() * 5
|
||||
"""urllib3 connection pool's maximum number of connections saved
|
||||
per pool. urllib3 uses 1 connection as default value, but this is
|
||||
not the best value when you are making a lot of possibly parallel
|
||||
requests to the same host, which is often the case here.
|
||||
cpu_count * 5 is used as default value to increase performance.
|
||||
"""
|
||||
|
||||
self.proxy = None
|
||||
"""Proxy URL
|
||||
"""
|
||||
self.proxy_headers = None
|
||||
"""Proxy headers
|
||||
"""
|
||||
self.safe_chars_for_path_param = ''
|
||||
"""Safe chars for path_param
|
||||
"""
|
||||
self.retries = None
|
||||
"""Adding retries to override urllib3 default value 3
|
||||
"""
|
||||
# Enable client side validation
|
||||
self.client_side_validation = True
|
||||
|
||||
self.socket_options = None
|
||||
"""Options to pass down to the underlying urllib3 socket
|
||||
"""
|
||||
|
||||
self.datetime_format = "%Y-%m-%dT%H:%M:%S.%f%z"
|
||||
"""datetime format
|
||||
"""
|
||||
|
||||
self.date_format = "%Y-%m-%d"
|
||||
"""date format
|
||||
"""
|
||||
|
||||
def __deepcopy__(self, memo):
|
||||
cls = self.__class__
|
||||
result = cls.__new__(cls)
|
||||
memo[id(self)] = result
|
||||
for k, v in self.__dict__.items():
|
||||
if k not in ('logger', 'logger_file_handler'):
|
||||
setattr(result, k, copy.deepcopy(v, memo))
|
||||
# shallow copy of loggers
|
||||
result.logger = copy.copy(self.logger)
|
||||
# use setters to configure loggers
|
||||
result.logger_file = self.logger_file
|
||||
result.debug = self.debug
|
||||
return result
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
object.__setattr__(self, name, value)
|
||||
|
||||
@classmethod
|
||||
def set_default(cls, default):
|
||||
"""Set default instance of configuration.
|
||||
|
||||
It stores default configuration, which can be
|
||||
returned by get_default_copy method.
|
||||
|
||||
:param default: object of Configuration
|
||||
"""
|
||||
cls._default = default
|
||||
|
||||
@classmethod
|
||||
def get_default_copy(cls):
|
||||
"""Deprecated. Please use `get_default` instead.
|
||||
|
||||
Deprecated. Please use `get_default` instead.
|
||||
|
||||
:return: The configuration object.
|
||||
"""
|
||||
return cls.get_default()
|
||||
|
||||
@classmethod
|
||||
def get_default(cls):
|
||||
"""Return the default configuration.
|
||||
|
||||
This method returns newly created, based on default constructor,
|
||||
object of Configuration class or returns a copy of default
|
||||
configuration.
|
||||
|
||||
:return: The configuration object.
|
||||
"""
|
||||
if cls._default is None:
|
||||
cls._default = Configuration()
|
||||
return cls._default
|
||||
|
||||
@property
|
||||
def logger_file(self):
|
||||
"""The logger file.
|
||||
|
||||
If the logger_file is None, then add stream handler and remove file
|
||||
handler. Otherwise, add file handler and remove stream handler.
|
||||
|
||||
:param value: The logger_file path.
|
||||
:type: str
|
||||
"""
|
||||
return self.__logger_file
|
||||
|
||||
@logger_file.setter
|
||||
def logger_file(self, value):
|
||||
"""The logger file.
|
||||
|
||||
If the logger_file is None, then add stream handler and remove file
|
||||
handler. Otherwise, add file handler and remove stream handler.
|
||||
|
||||
:param value: The logger_file path.
|
||||
:type: str
|
||||
"""
|
||||
self.__logger_file = value
|
||||
if self.__logger_file:
|
||||
# If set logging file,
|
||||
# then add file handler and remove stream handler.
|
||||
self.logger_file_handler = logging.FileHandler(self.__logger_file)
|
||||
self.logger_file_handler.setFormatter(self.logger_formatter)
|
||||
for _, logger in self.logger.items():
|
||||
logger.addHandler(self.logger_file_handler)
|
||||
|
||||
@property
|
||||
def debug(self):
|
||||
"""Debug status
|
||||
|
||||
:param value: The debug status, True or False.
|
||||
:type: bool
|
||||
"""
|
||||
return self.__debug
|
||||
|
||||
@debug.setter
|
||||
def debug(self, value):
|
||||
"""Debug status
|
||||
|
||||
:param value: The debug status, True or False.
|
||||
:type: bool
|
||||
"""
|
||||
self.__debug = value
|
||||
if self.__debug:
|
||||
# if debug status is True, turn on debug logging
|
||||
for _, logger in self.logger.items():
|
||||
logger.setLevel(logging.DEBUG)
|
||||
# turn on httplib debug
|
||||
httplib.HTTPConnection.debuglevel = 1
|
||||
else:
|
||||
# if debug status is False, turn off debug logging,
|
||||
# setting log level to default `logging.WARNING`
|
||||
for _, logger in self.logger.items():
|
||||
logger.setLevel(logging.WARNING)
|
||||
# turn off httplib debug
|
||||
httplib.HTTPConnection.debuglevel = 0
|
||||
|
||||
@property
|
||||
def logger_format(self):
|
||||
"""The logger format.
|
||||
|
||||
The logger_formatter will be updated when sets logger_format.
|
||||
|
||||
:param value: The format string.
|
||||
:type: str
|
||||
"""
|
||||
return self.__logger_format
|
||||
|
||||
@logger_format.setter
|
||||
def logger_format(self, value):
|
||||
"""The logger format.
|
||||
|
||||
The logger_formatter will be updated when sets logger_format.
|
||||
|
||||
:param value: The format string.
|
||||
:type: str
|
||||
"""
|
||||
self.__logger_format = value
|
||||
self.logger_formatter = logging.Formatter(self.__logger_format)
|
||||
|
||||
def get_api_key_with_prefix(self, identifier, alias=None):
|
||||
"""Gets API key (with prefix if set).
|
||||
|
||||
:param identifier: The identifier of apiKey.
|
||||
:param alias: The alternative identifier of apiKey.
|
||||
:return: The token for api key authentication.
|
||||
"""
|
||||
if self.refresh_api_key_hook is not None:
|
||||
self.refresh_api_key_hook(self)
|
||||
key = self.api_key.get(identifier, self.api_key.get(alias) if alias is not None else None)
|
||||
if key:
|
||||
prefix = self.api_key_prefix.get(identifier)
|
||||
if prefix:
|
||||
return "%s %s" % (prefix, key)
|
||||
else:
|
||||
return key
|
||||
|
||||
def get_basic_auth_token(self):
|
||||
"""Gets HTTP basic authentication header (string).
|
||||
|
||||
:return: The token for basic HTTP authentication.
|
||||
"""
|
||||
username = ""
|
||||
if self.username is not None:
|
||||
username = self.username
|
||||
password = ""
|
||||
if self.password is not None:
|
||||
password = self.password
|
||||
return urllib3.util.make_headers(
|
||||
basic_auth=username + ':' + password
|
||||
).get('authorization')
|
||||
|
||||
def auth_settings(self):
|
||||
"""Gets Auth Settings dict for api client.
|
||||
|
||||
:return: The Auth Settings information dict.
|
||||
"""
|
||||
auth = {}
|
||||
return auth
|
||||
|
||||
def to_debug_report(self):
|
||||
"""Gets the essential information for debugging.
|
||||
|
||||
:return: The report for debugging.
|
||||
"""
|
||||
return "Python SDK Debug Report:\n"\
|
||||
"OS: {env}\n"\
|
||||
"Python Version: {pyversion}\n"\
|
||||
"Version of the API: 0.1.0\n"\
|
||||
"SDK Package Version: 1.0.0".\
|
||||
format(env=sys.platform, pyversion=sys.version)
|
||||
|
||||
def get_host_settings(self):
|
||||
"""Gets an array of host settings
|
||||
|
||||
:return: An array of host settings
|
||||
"""
|
||||
return [
|
||||
{
|
||||
'url': "",
|
||||
'description': "No description provided",
|
||||
}
|
||||
]
|
||||
|
||||
def get_host_from_settings(self, index, variables=None, servers=None):
|
||||
"""Gets host URL based on the index and variables
|
||||
:param index: array index of the host settings
|
||||
:param variables: hash of variable and the corresponding value
|
||||
:param servers: an array of host settings or None
|
||||
:return: URL based on host settings
|
||||
"""
|
||||
if index is None:
|
||||
return self._base_path
|
||||
|
||||
variables = {} if variables is None else variables
|
||||
servers = self.get_host_settings() if servers is None else servers
|
||||
|
||||
try:
|
||||
server = servers[index]
|
||||
except IndexError:
|
||||
raise ValueError(
|
||||
"Invalid index {0} when selecting the host settings. "
|
||||
"Must be less than {1}".format(index, len(servers)))
|
||||
|
||||
url = server['url']
|
||||
|
||||
# go through variables and replace placeholders
|
||||
for variable_name, variable in server.get('variables', {}).items():
|
||||
used_value = variables.get(
|
||||
variable_name, variable['default_value'])
|
||||
|
||||
if 'enum_values' in variable \
|
||||
and used_value not in variable['enum_values']:
|
||||
raise ValueError(
|
||||
"The variable `{0}` in the host URL has invalid value "
|
||||
"{1}. Must be {2}.".format(
|
||||
variable_name, variables[variable_name],
|
||||
variable['enum_values']))
|
||||
|
||||
url = url.replace("{" + variable_name + "}", used_value)
|
||||
|
||||
return url
|
||||
|
||||
@property
|
||||
def host(self):
|
||||
"""Return generated host."""
|
||||
return self.get_host_from_settings(self.server_index, variables=self.server_variables)
|
||||
|
||||
@host.setter
|
||||
def host(self, value):
|
||||
"""Fix base path."""
|
||||
self._base_path = value
|
||||
self.server_index = None
|
||||
195
pkgs/clan-cli/tests/openapi_client/docs/DefaultApi.md
Normal file
195
pkgs/clan-cli/tests/openapi_client/docs/DefaultApi.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# openapi_client.DefaultApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**get_emulated_enpoints**](DefaultApi.md#get_emulated_enpoints) | **GET** /emulate | Get Emulated Enpoints
|
||||
[**health**](DefaultApi.md#health) | **GET** /health | Health
|
||||
[**root**](DefaultApi.md#root) | **GET** /{path_name} | Root
|
||||
|
||||
|
||||
# **get_emulated_enpoints**
|
||||
> str get_emulated_enpoints()
|
||||
|
||||
Get Emulated Enpoints
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.DefaultApi(api_client)
|
||||
|
||||
try:
|
||||
# Get Emulated Enpoints
|
||||
api_response = api_instance.get_emulated_enpoints()
|
||||
print("The response of DefaultApi->get_emulated_enpoints:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling DefaultApi->get_emulated_enpoints: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
This endpoint does not need any parameter.
|
||||
|
||||
### Return type
|
||||
|
||||
**str**
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: text/html
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **health**
|
||||
> Machine health()
|
||||
|
||||
Health
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.machine import Machine
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.DefaultApi(api_client)
|
||||
|
||||
try:
|
||||
# Health
|
||||
api_response = api_instance.health()
|
||||
print("The response of DefaultApi->health:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling DefaultApi->health: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
This endpoint does not need any parameter.
|
||||
|
||||
### Return type
|
||||
|
||||
[**Machine**](Machine.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **root**
|
||||
> root(path_name)
|
||||
|
||||
Root
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.DefaultApi(api_client)
|
||||
path_name = 'path_name_example' # str |
|
||||
|
||||
try:
|
||||
# Root
|
||||
api_instance.root(path_name)
|
||||
except Exception as e:
|
||||
print("Exception when calling DefaultApi->root: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**path_name** | **str**| |
|
||||
|
||||
### Return type
|
||||
|
||||
void (empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
621
pkgs/clan-cli/tests/openapi_client/docs/EntitiesApi.md
Normal file
621
pkgs/clan-cli/tests/openapi_client/docs/EntitiesApi.md
Normal file
@@ -0,0 +1,621 @@
|
||||
# openapi_client.EntitiesApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**attach_entity**](EntitiesApi.md#attach_entity) | **PUT** /api/v1/attach | Attach Entity
|
||||
[**create_entity**](EntitiesApi.md#create_entity) | **POST** /api/v1/entity | Create Entity
|
||||
[**delete_entity**](EntitiesApi.md#delete_entity) | **DELETE** /api/v1/entity | Delete Entity
|
||||
[**detach_entity**](EntitiesApi.md#detach_entity) | **PUT** /api/v1/detach | Detach Entity
|
||||
[**get_all_entities**](EntitiesApi.md#get_all_entities) | **GET** /api/v1/entities | Get All Entities
|
||||
[**get_attached_entities**](EntitiesApi.md#get_attached_entities) | **GET** /api/v1/attached_entities | Get Attached Entities
|
||||
[**get_entity_by_did**](EntitiesApi.md#get_entity_by_did) | **GET** /api/v1/entity | Get Entity By Did
|
||||
[**get_entity_by_roles**](EntitiesApi.md#get_entity_by_roles) | **GET** /api/v1/entity_by_roles | Get Entity By Roles
|
||||
[**is_attached**](EntitiesApi.md#is_attached) | **GET** /api/v1/is_attached | Is Attached
|
||||
|
||||
|
||||
# **attach_entity**
|
||||
> Dict[str, str] attach_entity(entity_did=entity_did, skip=skip, limit=limit)
|
||||
|
||||
Attach Entity
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Attach Entity
|
||||
api_response = api_instance.attach_entity(entity_did=entity_did, skip=skip, limit=limit)
|
||||
print("The response of EntitiesApi->attach_entity:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->attach_entity: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
**Dict[str, str]**
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **create_entity**
|
||||
> Entity create_entity(entity_create)
|
||||
|
||||
Create Entity
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.entity import Entity
|
||||
from openapi_client.models.entity_create import EntityCreate
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
entity_create = openapi_client.EntityCreate() # EntityCreate |
|
||||
|
||||
try:
|
||||
# Create Entity
|
||||
api_response = api_instance.create_entity(entity_create)
|
||||
print("The response of EntitiesApi->create_entity:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->create_entity: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_create** | [**EntityCreate**](EntityCreate.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Entity**](Entity.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **delete_entity**
|
||||
> Dict[str, str] delete_entity(entity_did=entity_did)
|
||||
|
||||
Delete Entity
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
|
||||
try:
|
||||
# Delete Entity
|
||||
api_response = api_instance.delete_entity(entity_did=entity_did)
|
||||
print("The response of EntitiesApi->delete_entity:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->delete_entity: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
|
||||
### Return type
|
||||
|
||||
**Dict[str, str]**
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **detach_entity**
|
||||
> Dict[str, str] detach_entity(entity_did=entity_did, skip=skip, limit=limit)
|
||||
|
||||
Detach Entity
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Detach Entity
|
||||
api_response = api_instance.detach_entity(entity_did=entity_did, skip=skip, limit=limit)
|
||||
print("The response of EntitiesApi->detach_entity:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->detach_entity: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
**Dict[str, str]**
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_all_entities**
|
||||
> List[Entity] get_all_entities(skip=skip, limit=limit)
|
||||
|
||||
Get All Entities
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.entity import Entity
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get All Entities
|
||||
api_response = api_instance.get_all_entities(skip=skip, limit=limit)
|
||||
print("The response of EntitiesApi->get_all_entities:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->get_all_entities: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Entity]**](Entity.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_attached_entities**
|
||||
> List[Entity] get_attached_entities(skip=skip, limit=limit)
|
||||
|
||||
Get Attached Entities
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.entity import Entity
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get Attached Entities
|
||||
api_response = api_instance.get_attached_entities(skip=skip, limit=limit)
|
||||
print("The response of EntitiesApi->get_attached_entities:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->get_attached_entities: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Entity]**](Entity.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_entity_by_did**
|
||||
> Entity get_entity_by_did(entity_did=entity_did)
|
||||
|
||||
Get Entity By Did
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.entity import Entity
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
|
||||
try:
|
||||
# Get Entity By Did
|
||||
api_response = api_instance.get_entity_by_did(entity_did=entity_did)
|
||||
print("The response of EntitiesApi->get_entity_by_did:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->get_entity_by_did: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
|
||||
### Return type
|
||||
|
||||
[**Entity**](Entity.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_entity_by_roles**
|
||||
> List[Entity] get_entity_by_roles(roles)
|
||||
|
||||
Get Entity By Roles
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.entity import Entity
|
||||
from openapi_client.models.role import Role
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
roles = [openapi_client.Role()] # List[Role] |
|
||||
|
||||
try:
|
||||
# Get Entity By Roles
|
||||
api_response = api_instance.get_entity_by_roles(roles)
|
||||
print("The response of EntitiesApi->get_entity_by_roles:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->get_entity_by_roles: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**roles** | [**List[Role]**](Role.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Entity]**](Entity.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **is_attached**
|
||||
> Dict[str, str] is_attached(entity_did=entity_did)
|
||||
|
||||
Is Attached
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EntitiesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
|
||||
try:
|
||||
# Is Attached
|
||||
api_response = api_instance.is_attached(entity_did=entity_did)
|
||||
print("The response of EntitiesApi->is_attached:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EntitiesApi->is_attached: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
|
||||
### Return type
|
||||
|
||||
**Dict[str, str]**
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
36
pkgs/clan-cli/tests/openapi_client/docs/Entity.md
Normal file
36
pkgs/clan-cli/tests/openapi_client/docs/Entity.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Entity
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**did** | **str** | |
|
||||
**name** | **str** | |
|
||||
**ip** | **str** | |
|
||||
**network** | **str** | |
|
||||
**visible** | **bool** | |
|
||||
**other** | **object** | |
|
||||
**attached** | **bool** | |
|
||||
**stop_health_task** | **bool** | |
|
||||
**roles** | [**List[Role]**](Role.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.entity import Entity
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Entity from a JSON string
|
||||
entity_instance = Entity.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print Entity.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
entity_dict = entity_instance.to_dict()
|
||||
# create an instance of Entity from a dict
|
||||
entity_form_dict = entity.from_dict(entity_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
34
pkgs/clan-cli/tests/openapi_client/docs/EntityCreate.md
Normal file
34
pkgs/clan-cli/tests/openapi_client/docs/EntityCreate.md
Normal file
@@ -0,0 +1,34 @@
|
||||
# EntityCreate
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**did** | **str** | |
|
||||
**name** | **str** | |
|
||||
**ip** | **str** | |
|
||||
**network** | **str** | |
|
||||
**visible** | **bool** | |
|
||||
**other** | **object** | |
|
||||
**roles** | [**List[Role]**](Role.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.entity_create import EntityCreate
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of EntityCreate from a JSON string
|
||||
entity_create_instance = EntityCreate.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print EntityCreate.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
entity_create_dict = entity_create_instance.to_dict()
|
||||
# create an instance of EntityCreate from a dict
|
||||
entity_create_form_dict = entity_create.from_dict(entity_create_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
39
pkgs/clan-cli/tests/openapi_client/docs/Eventmessage.md
Normal file
39
pkgs/clan-cli/tests/openapi_client/docs/Eventmessage.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Eventmessage
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**timestamp** | **int** | |
|
||||
**group** | **int** | |
|
||||
**group_id** | **int** | |
|
||||
**msg_type** | **int** | |
|
||||
**src_did** | **str** | |
|
||||
**des_did** | **str** | |
|
||||
**msg** | **object** | |
|
||||
**id** | **int** | |
|
||||
**des_name** | **str** | | [optional]
|
||||
**src_name** | **str** | | [optional]
|
||||
**msg_type_name** | **str** | | [optional]
|
||||
**group_name** | **str** | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.eventmessage import Eventmessage
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Eventmessage from a JSON string
|
||||
eventmessage_instance = Eventmessage.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print Eventmessage.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
eventmessage_dict = eventmessage_instance.to_dict()
|
||||
# create an instance of Eventmessage from a dict
|
||||
eventmessage_form_dict = eventmessage.from_dict(eventmessage_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# EventmessageCreate
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**timestamp** | **int** | |
|
||||
**group** | **int** | |
|
||||
**group_id** | **int** | |
|
||||
**msg_type** | **int** | |
|
||||
**src_did** | **str** | |
|
||||
**des_did** | **str** | |
|
||||
**msg** | **object** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.eventmessage_create import EventmessageCreate
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of EventmessageCreate from a JSON string
|
||||
eventmessage_create_instance = EventmessageCreate.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print EventmessageCreate.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
eventmessage_create_dict = eventmessage_create_instance.to_dict()
|
||||
# create an instance of EventmessageCreate from a dict
|
||||
eventmessage_create_form_dict = eventmessage_create.from_dict(eventmessage_create_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
142
pkgs/clan-cli/tests/openapi_client/docs/EventmessagesApi.md
Normal file
142
pkgs/clan-cli/tests/openapi_client/docs/EventmessagesApi.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# openapi_client.EventmessagesApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**create_eventmessage**](EventmessagesApi.md#create_eventmessage) | **POST** /api/v1/event_message | Create Eventmessage
|
||||
[**get_all_eventmessages**](EventmessagesApi.md#get_all_eventmessages) | **GET** /api/v1/event_messages | Get All Eventmessages
|
||||
|
||||
|
||||
# **create_eventmessage**
|
||||
> Eventmessage create_eventmessage(eventmessage_create)
|
||||
|
||||
Create Eventmessage
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.eventmessage import Eventmessage
|
||||
from openapi_client.models.eventmessage_create import EventmessageCreate
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EventmessagesApi(api_client)
|
||||
eventmessage_create = openapi_client.EventmessageCreate() # EventmessageCreate |
|
||||
|
||||
try:
|
||||
# Create Eventmessage
|
||||
api_response = api_instance.create_eventmessage(eventmessage_create)
|
||||
print("The response of EventmessagesApi->create_eventmessage:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling EventmessagesApi->create_eventmessage: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**eventmessage_create** | [**EventmessageCreate**](EventmessageCreate.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Eventmessage**](Eventmessage.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_all_eventmessages**
|
||||
> get_all_eventmessages(skip=skip, limit=limit)
|
||||
|
||||
Get All Eventmessages
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.EventmessagesApi(api_client)
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get All Eventmessages
|
||||
api_instance.get_all_eventmessages(skip=skip, limit=limit)
|
||||
except Exception as e:
|
||||
print("Exception when calling EventmessagesApi->get_all_eventmessages: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
void (empty response body)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
# HTTPValidationError
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**detail** | [**List[ValidationError]**](ValidationError.md) | | [optional]
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.http_validation_error import HTTPValidationError
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of HTTPValidationError from a JSON string
|
||||
http_validation_error_instance = HTTPValidationError.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print HTTPValidationError.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
http_validation_error_dict = http_validation_error_instance.to_dict()
|
||||
# create an instance of HTTPValidationError from a dict
|
||||
http_validation_error_form_dict = http_validation_error.from_dict(http_validation_error_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
29
pkgs/clan-cli/tests/openapi_client/docs/Machine.md
Normal file
29
pkgs/clan-cli/tests/openapi_client/docs/Machine.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Machine
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**name** | **str** | |
|
||||
**status** | [**Status**](Status.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.machine import Machine
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Machine from a JSON string
|
||||
machine_instance = Machine.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print Machine.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
machine_dict = machine_instance.to_dict()
|
||||
# create an instance of Machine from a dict
|
||||
machine_form_dict = machine.from_dict(machine_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
77
pkgs/clan-cli/tests/openapi_client/docs/RepositoriesApi.md
Normal file
77
pkgs/clan-cli/tests/openapi_client/docs/RepositoriesApi.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# openapi_client.RepositoriesApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**get_all_repositories**](RepositoriesApi.md#get_all_repositories) | **GET** /api/v1/repositories | Get All Repositories
|
||||
|
||||
|
||||
# **get_all_repositories**
|
||||
> List[Service] get_all_repositories(skip=skip, limit=limit)
|
||||
|
||||
Get All Repositories
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.RepositoriesApi(api_client)
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get All Repositories
|
||||
api_response = api_instance.get_all_repositories(skip=skip, limit=limit)
|
||||
print("The response of RepositoriesApi->get_all_repositories:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling RepositoriesApi->get_all_repositories: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Service]**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
32
pkgs/clan-cli/tests/openapi_client/docs/Resolution.md
Normal file
32
pkgs/clan-cli/tests/openapi_client/docs/Resolution.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# Resolution
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**requester_name** | **str** | |
|
||||
**requester_did** | **str** | |
|
||||
**resolved_did** | **str** | |
|
||||
**other** | **object** | |
|
||||
**timestamp** | **datetime** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.resolution import Resolution
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Resolution from a JSON string
|
||||
resolution_instance = Resolution.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print Resolution.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
resolution_dict = resolution_instance.to_dict()
|
||||
# create an instance of Resolution from a dict
|
||||
resolution_form_dict = resolution.from_dict(resolution_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
77
pkgs/clan-cli/tests/openapi_client/docs/ResolutionApi.md
Normal file
77
pkgs/clan-cli/tests/openapi_client/docs/ResolutionApi.md
Normal file
@@ -0,0 +1,77 @@
|
||||
# openapi_client.ResolutionApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**get_all_resolutions**](ResolutionApi.md#get_all_resolutions) | **GET** /api/v1/resolutions | Get All Resolutions
|
||||
|
||||
|
||||
# **get_all_resolutions**
|
||||
> List[Resolution] get_all_resolutions(skip=skip, limit=limit)
|
||||
|
||||
Get All Resolutions
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.resolution import Resolution
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ResolutionApi(api_client)
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get All Resolutions
|
||||
api_response = api_instance.get_all_resolutions(skip=skip, limit=limit)
|
||||
print("The response of ResolutionApi->get_all_resolutions:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ResolutionApi->get_all_resolutions: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Resolution]**](Resolution.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
11
pkgs/clan-cli/tests/openapi_client/docs/Role.md
Normal file
11
pkgs/clan-cli/tests/openapi_client/docs/Role.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Role
|
||||
|
||||
An enumeration.
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
36
pkgs/clan-cli/tests/openapi_client/docs/Service.md
Normal file
36
pkgs/clan-cli/tests/openapi_client/docs/Service.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Service
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**uuid** | **str** | |
|
||||
**service_name** | **str** | |
|
||||
**service_type** | **str** | |
|
||||
**endpoint_url** | **str** | |
|
||||
**other** | **object** | |
|
||||
**entity_did** | **str** | |
|
||||
**status** | **object** | |
|
||||
**action** | **object** | |
|
||||
**usage** | [**List[ServiceUsage]**](ServiceUsage.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.service import Service
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of Service from a JSON string
|
||||
service_instance = Service.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print Service.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
service_dict = service_instance.to_dict()
|
||||
# create an instance of Service from a dict
|
||||
service_form_dict = service.from_dict(service_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
36
pkgs/clan-cli/tests/openapi_client/docs/ServiceCreate.md
Normal file
36
pkgs/clan-cli/tests/openapi_client/docs/ServiceCreate.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# ServiceCreate
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**uuid** | **str** | |
|
||||
**service_name** | **str** | |
|
||||
**service_type** | **str** | |
|
||||
**endpoint_url** | **str** | |
|
||||
**other** | **object** | |
|
||||
**entity_did** | **str** | |
|
||||
**status** | **object** | |
|
||||
**action** | **object** | |
|
||||
**usage** | [**List[ServiceUsageCreate]**](ServiceUsageCreate.md) | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.service_create import ServiceCreate
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ServiceCreate from a JSON string
|
||||
service_create_instance = ServiceCreate.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print ServiceCreate.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
service_create_dict = service_create_instance.to_dict()
|
||||
# create an instance of ServiceCreate from a dict
|
||||
service_create_form_dict = service_create.from_dict(service_create_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
29
pkgs/clan-cli/tests/openapi_client/docs/ServiceUsage.md
Normal file
29
pkgs/clan-cli/tests/openapi_client/docs/ServiceUsage.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# ServiceUsage
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**times_consumed** | **int** | |
|
||||
**consumer_entity_did** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.service_usage import ServiceUsage
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ServiceUsage from a JSON string
|
||||
service_usage_instance = ServiceUsage.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print ServiceUsage.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
service_usage_dict = service_usage_instance.to_dict()
|
||||
# create an instance of ServiceUsage from a dict
|
||||
service_usage_form_dict = service_usage.from_dict(service_usage_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
# ServiceUsageCreate
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**times_consumed** | **int** | |
|
||||
**consumer_entity_did** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.service_usage_create import ServiceUsageCreate
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ServiceUsageCreate from a JSON string
|
||||
service_usage_create_instance = ServiceUsageCreate.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print ServiceUsageCreate.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
service_usage_create_dict = service_usage_create_instance.to_dict()
|
||||
# create an instance of ServiceUsageCreate from a dict
|
||||
service_usage_create_form_dict = service_usage_create.from_dict(service_usage_create_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
636
pkgs/clan-cli/tests/openapi_client/docs/ServicesApi.md
Normal file
636
pkgs/clan-cli/tests/openapi_client/docs/ServicesApi.md
Normal file
@@ -0,0 +1,636 @@
|
||||
# openapi_client.ServicesApi
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**add_service_usage**](ServicesApi.md#add_service_usage) | **POST** /api/v1/service_usage | Add Service Usage
|
||||
[**create_service**](ServicesApi.md#create_service) | **POST** /api/v1/service | Create Service
|
||||
[**delete_service**](ServicesApi.md#delete_service) | **DELETE** /api/v1/service | Delete Service
|
||||
[**get_all_services**](ServicesApi.md#get_all_services) | **GET** /api/v1/services | Get All Services
|
||||
[**get_service_by_did**](ServicesApi.md#get_service_by_did) | **GET** /api/v1/service_by_did | Get Service By Did
|
||||
[**get_service_by_uuid**](ServicesApi.md#get_service_by_uuid) | **GET** /api/v1/service | Get Service By Uuid
|
||||
[**get_services_without_entity**](ServicesApi.md#get_services_without_entity) | **GET** /api/v1/services_without_entity | Get Services Without Entity
|
||||
[**inc_service_usage**](ServicesApi.md#inc_service_usage) | **PUT** /api/v1/inc_service_usage | Inc Service Usage
|
||||
[**update_service**](ServicesApi.md#update_service) | **PUT** /api/v1/service | Update Service
|
||||
|
||||
|
||||
# **add_service_usage**
|
||||
> Service add_service_usage(service_usage_create, service_uuid=service_uuid)
|
||||
|
||||
Add Service Usage
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.service_usage_create import ServiceUsageCreate
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
service_usage_create = openapi_client.ServiceUsageCreate() # ServiceUsageCreate |
|
||||
service_uuid = 'bdd640fb-0667-1ad1-1c80-317fa3b1799d' # str | (optional) (default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d')
|
||||
|
||||
try:
|
||||
# Add Service Usage
|
||||
api_response = api_instance.add_service_usage(service_usage_create, service_uuid=service_uuid)
|
||||
print("The response of ServicesApi->add_service_usage:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->add_service_usage: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**service_usage_create** | [**ServiceUsageCreate**](ServiceUsageCreate.md)| |
|
||||
**service_uuid** | **str**| | [optional] [default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d']
|
||||
|
||||
### Return type
|
||||
|
||||
[**Service**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **create_service**
|
||||
> Service create_service(service_create)
|
||||
|
||||
Create Service
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.service_create import ServiceCreate
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
service_create = openapi_client.ServiceCreate() # ServiceCreate |
|
||||
|
||||
try:
|
||||
# Create Service
|
||||
api_response = api_instance.create_service(service_create)
|
||||
print("The response of ServicesApi->create_service:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->create_service: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**service_create** | [**ServiceCreate**](ServiceCreate.md)| |
|
||||
|
||||
### Return type
|
||||
|
||||
[**Service**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **delete_service**
|
||||
> Dict[str, str] delete_service(entity_did=entity_did)
|
||||
|
||||
Delete Service
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
|
||||
try:
|
||||
# Delete Service
|
||||
api_response = api_instance.delete_service(entity_did=entity_did)
|
||||
print("The response of ServicesApi->delete_service:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->delete_service: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
|
||||
### Return type
|
||||
|
||||
**Dict[str, str]**
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_all_services**
|
||||
> List[Service] get_all_services(skip=skip, limit=limit)
|
||||
|
||||
Get All Services
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get All Services
|
||||
api_response = api_instance.get_all_services(skip=skip, limit=limit)
|
||||
print("The response of ServicesApi->get_all_services:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->get_all_services: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Service]**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_service_by_did**
|
||||
> List[Service] get_service_by_did(entity_did=entity_did, skip=skip, limit=limit)
|
||||
|
||||
Get Service By Did
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get Service By Did
|
||||
api_response = api_instance.get_service_by_did(entity_did=entity_did, skip=skip, limit=limit)
|
||||
print("The response of ServicesApi->get_service_by_did:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->get_service_by_did: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Service]**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_service_by_uuid**
|
||||
> Service get_service_by_uuid(uuid=uuid, skip=skip, limit=limit)
|
||||
|
||||
Get Service By Uuid
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
uuid = 'bdd640fb-0667-1ad1-1c80-317fa3b1799d' # str | (optional) (default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d')
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get Service By Uuid
|
||||
api_response = api_instance.get_service_by_uuid(uuid=uuid, skip=skip, limit=limit)
|
||||
print("The response of ServicesApi->get_service_by_uuid:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->get_service_by_uuid: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**uuid** | **str**| | [optional] [default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d']
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**Service**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **get_services_without_entity**
|
||||
> List[Service] get_services_without_entity(entity_did=entity_did, skip=skip, limit=limit)
|
||||
|
||||
Get Services Without Entity
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
skip = 0 # int | (optional) (default to 0)
|
||||
limit = 100 # int | (optional) (default to 100)
|
||||
|
||||
try:
|
||||
# Get Services Without Entity
|
||||
api_response = api_instance.get_services_without_entity(entity_did=entity_did, skip=skip, limit=limit)
|
||||
print("The response of ServicesApi->get_services_without_entity:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->get_services_without_entity: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
**skip** | **int**| | [optional] [default to 0]
|
||||
**limit** | **int**| | [optional] [default to 100]
|
||||
|
||||
### Return type
|
||||
|
||||
[**List[Service]**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **inc_service_usage**
|
||||
> Service inc_service_usage(service_usage_create, consumer_entity_did=consumer_entity_did, service_uuid=service_uuid)
|
||||
|
||||
Inc Service Usage
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.service_usage_create import ServiceUsageCreate
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
service_usage_create = openapi_client.ServiceUsageCreate() # ServiceUsageCreate |
|
||||
consumer_entity_did = 'did:sov:test:120' # str | (optional) (default to 'did:sov:test:120')
|
||||
service_uuid = 'bdd640fb-0667-1ad1-1c80-317fa3b1799d' # str | (optional) (default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d')
|
||||
|
||||
try:
|
||||
# Inc Service Usage
|
||||
api_response = api_instance.inc_service_usage(service_usage_create, consumer_entity_did=consumer_entity_did, service_uuid=service_uuid)
|
||||
print("The response of ServicesApi->inc_service_usage:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->inc_service_usage: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**service_usage_create** | [**ServiceUsageCreate**](ServiceUsageCreate.md)| |
|
||||
**consumer_entity_did** | **str**| | [optional] [default to 'did:sov:test:120']
|
||||
**service_uuid** | **str**| | [optional] [default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d']
|
||||
|
||||
### Return type
|
||||
|
||||
[**Service**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
# **update_service**
|
||||
> Service update_service(service_create, uuid=uuid)
|
||||
|
||||
Update Service
|
||||
|
||||
### Example
|
||||
|
||||
```python
|
||||
import time
|
||||
import os
|
||||
import openapi_client
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.service_create import ServiceCreate
|
||||
from openapi_client.rest import ApiException
|
||||
from pprint import pprint
|
||||
|
||||
# Defining the host is optional and defaults to http://localhost
|
||||
# See configuration.py for a list of all supported configuration parameters.
|
||||
configuration = openapi_client.Configuration(
|
||||
host = "http://localhost"
|
||||
)
|
||||
|
||||
|
||||
# Enter a context with an instance of the API client
|
||||
with openapi_client.ApiClient(configuration) as api_client:
|
||||
# Create an instance of the API class
|
||||
api_instance = openapi_client.ServicesApi(api_client)
|
||||
service_create = openapi_client.ServiceCreate() # ServiceCreate |
|
||||
uuid = 'bdd640fb-0667-1ad1-1c80-317fa3b1799d' # str | (optional) (default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d')
|
||||
|
||||
try:
|
||||
# Update Service
|
||||
api_response = api_instance.update_service(service_create, uuid=uuid)
|
||||
print("The response of ServicesApi->update_service:\n")
|
||||
pprint(api_response)
|
||||
except Exception as e:
|
||||
print("Exception when calling ServicesApi->update_service: %s\n" % e)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Parameters
|
||||
|
||||
Name | Type | Description | Notes
|
||||
------------- | ------------- | ------------- | -------------
|
||||
**service_create** | [**ServiceCreate**](ServiceCreate.md)| |
|
||||
**uuid** | **str**| | [optional] [default to 'bdd640fb-0667-1ad1-1c80-317fa3b1799d']
|
||||
|
||||
### Return type
|
||||
|
||||
[**Service**](Service.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: application/json
|
||||
- **Accept**: application/json
|
||||
|
||||
### HTTP response details
|
||||
| Status code | Description | Response headers |
|
||||
|-------------|-------------|------------------|
|
||||
**200** | Successful Response | - |
|
||||
**422** | Validation Error | - |
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
||||
11
pkgs/clan-cli/tests/openapi_client/docs/Status.md
Normal file
11
pkgs/clan-cli/tests/openapi_client/docs/Status.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Status
|
||||
|
||||
An enumeration.
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
30
pkgs/clan-cli/tests/openapi_client/docs/ValidationError.md
Normal file
30
pkgs/clan-cli/tests/openapi_client/docs/ValidationError.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# ValidationError
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**loc** | [**List[ValidationErrorLocInner]**](ValidationErrorLocInner.md) | |
|
||||
**msg** | **str** | |
|
||||
**type** | **str** | |
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.validation_error import ValidationError
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ValidationError from a JSON string
|
||||
validation_error_instance = ValidationError.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print ValidationError.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
validation_error_dict = validation_error_instance.to_dict()
|
||||
# create an instance of ValidationError from a dict
|
||||
validation_error_form_dict = validation_error.from_dict(validation_error_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# ValidationErrorLocInner
|
||||
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from openapi_client.models.validation_error_loc_inner import ValidationErrorLocInner
|
||||
|
||||
# TODO update the JSON string below
|
||||
json = "{}"
|
||||
# create an instance of ValidationErrorLocInner from a JSON string
|
||||
validation_error_loc_inner_instance = ValidationErrorLocInner.from_json(json)
|
||||
# print the JSON string representation of the object
|
||||
print ValidationErrorLocInner.to_json()
|
||||
|
||||
# convert the object into a dict
|
||||
validation_error_loc_inner_dict = validation_error_loc_inner_instance.to_dict()
|
||||
# create an instance of ValidationErrorLocInner from a dict
|
||||
validation_error_loc_inner_form_dict = validation_error_loc_inner.from_dict(validation_error_loc_inner_dict)
|
||||
```
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
166
pkgs/clan-cli/tests/openapi_client/exceptions.py
Normal file
166
pkgs/clan-cli/tests/openapi_client/exceptions.py
Normal file
@@ -0,0 +1,166 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
class OpenApiException(Exception):
|
||||
"""The base exception class for all OpenAPIExceptions"""
|
||||
|
||||
|
||||
class ApiTypeError(OpenApiException, TypeError):
|
||||
def __init__(self, msg, path_to_item=None, valid_classes=None,
|
||||
key_type=None) -> None:
|
||||
""" Raises an exception for TypeErrors
|
||||
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (list): a list of keys an indices to get to the
|
||||
current_item
|
||||
None if unset
|
||||
valid_classes (tuple): the primitive classes that current item
|
||||
should be an instance of
|
||||
None if unset
|
||||
key_type (bool): False if our value is a value in a dict
|
||||
True if it is a key in a dict
|
||||
False if our item is an item in a list
|
||||
None if unset
|
||||
"""
|
||||
self.path_to_item = path_to_item
|
||||
self.valid_classes = valid_classes
|
||||
self.key_type = key_type
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiTypeError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiValueError(OpenApiException, ValueError):
|
||||
def __init__(self, msg, path_to_item=None) -> None:
|
||||
"""
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (list) the path to the exception in the
|
||||
received_data dict. None if unset
|
||||
"""
|
||||
|
||||
self.path_to_item = path_to_item
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiValueError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiAttributeError(OpenApiException, AttributeError):
|
||||
def __init__(self, msg, path_to_item=None) -> None:
|
||||
"""
|
||||
Raised when an attribute reference or assignment fails.
|
||||
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (None/list) the path to the exception in the
|
||||
received_data dict
|
||||
"""
|
||||
self.path_to_item = path_to_item
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiAttributeError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiKeyError(OpenApiException, KeyError):
|
||||
def __init__(self, msg, path_to_item=None) -> None:
|
||||
"""
|
||||
Args:
|
||||
msg (str): the exception message
|
||||
|
||||
Keyword Args:
|
||||
path_to_item (None/list) the path to the exception in the
|
||||
received_data dict
|
||||
"""
|
||||
self.path_to_item = path_to_item
|
||||
full_msg = msg
|
||||
if path_to_item:
|
||||
full_msg = "{0} at {1}".format(msg, render_path(path_to_item))
|
||||
super(ApiKeyError, self).__init__(full_msg)
|
||||
|
||||
|
||||
class ApiException(OpenApiException):
|
||||
|
||||
def __init__(self, status=None, reason=None, http_resp=None) -> None:
|
||||
if http_resp:
|
||||
self.status = http_resp.status
|
||||
self.reason = http_resp.reason
|
||||
self.body = http_resp.data
|
||||
self.headers = http_resp.getheaders()
|
||||
else:
|
||||
self.status = status
|
||||
self.reason = reason
|
||||
self.body = None
|
||||
self.headers = None
|
||||
|
||||
def __str__(self):
|
||||
"""Custom error messages for exception"""
|
||||
error_message = "({0})\n"\
|
||||
"Reason: {1}\n".format(self.status, self.reason)
|
||||
if self.headers:
|
||||
error_message += "HTTP response headers: {0}\n".format(
|
||||
self.headers)
|
||||
|
||||
if self.body:
|
||||
error_message += "HTTP response body: {0}\n".format(self.body)
|
||||
|
||||
return error_message
|
||||
|
||||
class BadRequestException(ApiException):
|
||||
|
||||
def __init__(self, status=None, reason=None, http_resp=None) -> None:
|
||||
super(BadRequestException, self).__init__(status, reason, http_resp)
|
||||
|
||||
class NotFoundException(ApiException):
|
||||
|
||||
def __init__(self, status=None, reason=None, http_resp=None) -> None:
|
||||
super(NotFoundException, self).__init__(status, reason, http_resp)
|
||||
|
||||
|
||||
class UnauthorizedException(ApiException):
|
||||
|
||||
def __init__(self, status=None, reason=None, http_resp=None) -> None:
|
||||
super(UnauthorizedException, self).__init__(status, reason, http_resp)
|
||||
|
||||
|
||||
class ForbiddenException(ApiException):
|
||||
|
||||
def __init__(self, status=None, reason=None, http_resp=None) -> None:
|
||||
super(ForbiddenException, self).__init__(status, reason, http_resp)
|
||||
|
||||
|
||||
class ServiceException(ApiException):
|
||||
|
||||
def __init__(self, status=None, reason=None, http_resp=None) -> None:
|
||||
super(ServiceException, self).__init__(status, reason, http_resp)
|
||||
|
||||
|
||||
def render_path(path_to_item):
|
||||
"""Returns a string representation of a path"""
|
||||
result = ""
|
||||
for pth in path_to_item:
|
||||
if isinstance(pth, int):
|
||||
result += "[{0}]".format(pth)
|
||||
else:
|
||||
result += "['{0}']".format(pth)
|
||||
return result
|
||||
31
pkgs/clan-cli/tests/openapi_client/models/__init__.py
Normal file
31
pkgs/clan-cli/tests/openapi_client/models/__init__.py
Normal file
@@ -0,0 +1,31 @@
|
||||
# coding: utf-8
|
||||
|
||||
# flake8: noqa
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
# import models into model package
|
||||
from openapi_client.models.entity import Entity
|
||||
from openapi_client.models.entity_create import EntityCreate
|
||||
from openapi_client.models.eventmessage import Eventmessage
|
||||
from openapi_client.models.eventmessage_create import EventmessageCreate
|
||||
from openapi_client.models.http_validation_error import HTTPValidationError
|
||||
from openapi_client.models.machine import Machine
|
||||
from openapi_client.models.resolution import Resolution
|
||||
from openapi_client.models.role import Role
|
||||
from openapi_client.models.service import Service
|
||||
from openapi_client.models.service_create import ServiceCreate
|
||||
from openapi_client.models.service_usage import ServiceUsage
|
||||
from openapi_client.models.service_usage_create import ServiceUsageCreate
|
||||
from openapi_client.models.status import Status
|
||||
from openapi_client.models.validation_error import ValidationError
|
||||
from openapi_client.models.validation_error_loc_inner import ValidationErrorLocInner
|
||||
88
pkgs/clan-cli/tests/openapi_client/models/entity.py
Normal file
88
pkgs/clan-cli/tests/openapi_client/models/entity.py
Normal file
@@ -0,0 +1,88 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import Any, Dict, List
|
||||
from pydantic import BaseModel, Field, StrictBool, StrictStr, conlist
|
||||
from openapi_client.models.role import Role
|
||||
|
||||
class Entity(BaseModel):
|
||||
"""
|
||||
Entity
|
||||
"""
|
||||
did: StrictStr = Field(...)
|
||||
name: StrictStr = Field(...)
|
||||
ip: StrictStr = Field(...)
|
||||
network: StrictStr = Field(...)
|
||||
visible: StrictBool = Field(...)
|
||||
other: Dict[str, Any] = Field(...)
|
||||
attached: StrictBool = Field(...)
|
||||
stop_health_task: StrictBool = Field(...)
|
||||
roles: conlist(Role) = Field(...)
|
||||
__properties = ["did", "name", "ip", "network", "visible", "other", "attached", "stop_health_task", "roles"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Entity:
|
||||
"""Create an instance of Entity from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> Entity:
|
||||
"""Create an instance of Entity from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return Entity.parse_obj(obj)
|
||||
|
||||
_obj = Entity.parse_obj({
|
||||
"did": obj.get("did"),
|
||||
"name": obj.get("name"),
|
||||
"ip": obj.get("ip"),
|
||||
"network": obj.get("network"),
|
||||
"visible": obj.get("visible"),
|
||||
"other": obj.get("other"),
|
||||
"attached": obj.get("attached"),
|
||||
"stop_health_task": obj.get("stop_health_task"),
|
||||
"roles": obj.get("roles")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
84
pkgs/clan-cli/tests/openapi_client/models/entity_create.py
Normal file
84
pkgs/clan-cli/tests/openapi_client/models/entity_create.py
Normal file
@@ -0,0 +1,84 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import Any, Dict, List
|
||||
from pydantic import BaseModel, Field, StrictBool, StrictStr, conlist
|
||||
from openapi_client.models.role import Role
|
||||
|
||||
class EntityCreate(BaseModel):
|
||||
"""
|
||||
EntityCreate
|
||||
"""
|
||||
did: StrictStr = Field(...)
|
||||
name: StrictStr = Field(...)
|
||||
ip: StrictStr = Field(...)
|
||||
network: StrictStr = Field(...)
|
||||
visible: StrictBool = Field(...)
|
||||
other: Dict[str, Any] = Field(...)
|
||||
roles: conlist(Role) = Field(...)
|
||||
__properties = ["did", "name", "ip", "network", "visible", "other", "roles"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> EntityCreate:
|
||||
"""Create an instance of EntityCreate from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> EntityCreate:
|
||||
"""Create an instance of EntityCreate from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return EntityCreate.parse_obj(obj)
|
||||
|
||||
_obj = EntityCreate.parse_obj({
|
||||
"did": obj.get("did"),
|
||||
"name": obj.get("name"),
|
||||
"ip": obj.get("ip"),
|
||||
"network": obj.get("network"),
|
||||
"visible": obj.get("visible"),
|
||||
"other": obj.get("other"),
|
||||
"roles": obj.get("roles")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
93
pkgs/clan-cli/tests/openapi_client/models/eventmessage.py
Normal file
93
pkgs/clan-cli/tests/openapi_client/models/eventmessage.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import Any, Dict, Optional
|
||||
from pydantic import BaseModel, Field, StrictInt, StrictStr
|
||||
|
||||
class Eventmessage(BaseModel):
|
||||
"""
|
||||
Eventmessage
|
||||
"""
|
||||
timestamp: StrictInt = Field(...)
|
||||
group: StrictInt = Field(...)
|
||||
group_id: StrictInt = Field(...)
|
||||
msg_type: StrictInt = Field(...)
|
||||
src_did: StrictStr = Field(...)
|
||||
des_did: StrictStr = Field(...)
|
||||
msg: Dict[str, Any] = Field(...)
|
||||
id: StrictInt = Field(...)
|
||||
des_name: Optional[StrictStr] = None
|
||||
src_name: Optional[StrictStr] = None
|
||||
msg_type_name: Optional[StrictStr] = None
|
||||
group_name: Optional[StrictStr] = None
|
||||
__properties = ["timestamp", "group", "group_id", "msg_type", "src_did", "des_did", "msg", "id", "des_name", "src_name", "msg_type_name", "group_name"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Eventmessage:
|
||||
"""Create an instance of Eventmessage from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> Eventmessage:
|
||||
"""Create an instance of Eventmessage from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return Eventmessage.parse_obj(obj)
|
||||
|
||||
_obj = Eventmessage.parse_obj({
|
||||
"timestamp": obj.get("timestamp"),
|
||||
"group": obj.get("group"),
|
||||
"group_id": obj.get("group_id"),
|
||||
"msg_type": obj.get("msg_type"),
|
||||
"src_did": obj.get("src_did"),
|
||||
"des_did": obj.get("des_did"),
|
||||
"msg": obj.get("msg"),
|
||||
"id": obj.get("id"),
|
||||
"des_name": obj.get("des_name"),
|
||||
"src_name": obj.get("src_name"),
|
||||
"msg_type_name": obj.get("msg_type_name"),
|
||||
"group_name": obj.get("group_name")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import Any, Dict
|
||||
from pydantic import BaseModel, Field, StrictInt, StrictStr
|
||||
|
||||
class EventmessageCreate(BaseModel):
|
||||
"""
|
||||
EventmessageCreate
|
||||
"""
|
||||
timestamp: StrictInt = Field(...)
|
||||
group: StrictInt = Field(...)
|
||||
group_id: StrictInt = Field(...)
|
||||
msg_type: StrictInt = Field(...)
|
||||
src_did: StrictStr = Field(...)
|
||||
des_did: StrictStr = Field(...)
|
||||
msg: Dict[str, Any] = Field(...)
|
||||
__properties = ["timestamp", "group", "group_id", "msg_type", "src_did", "des_did", "msg"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> EventmessageCreate:
|
||||
"""Create an instance of EventmessageCreate from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> EventmessageCreate:
|
||||
"""Create an instance of EventmessageCreate from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return EventmessageCreate.parse_obj(obj)
|
||||
|
||||
_obj = EventmessageCreate.parse_obj({
|
||||
"timestamp": obj.get("timestamp"),
|
||||
"group": obj.get("group"),
|
||||
"group_id": obj.get("group_id"),
|
||||
"msg_type": obj.get("msg_type"),
|
||||
"src_did": obj.get("src_did"),
|
||||
"des_did": obj.get("des_did"),
|
||||
"msg": obj.get("msg")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import List, Optional
|
||||
from pydantic import BaseModel, conlist
|
||||
from openapi_client.models.validation_error import ValidationError
|
||||
|
||||
class HTTPValidationError(BaseModel):
|
||||
"""
|
||||
HTTPValidationError
|
||||
"""
|
||||
detail: Optional[conlist(ValidationError)] = None
|
||||
__properties = ["detail"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> HTTPValidationError:
|
||||
"""Create an instance of HTTPValidationError from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in detail (list)
|
||||
_items = []
|
||||
if self.detail:
|
||||
for _item in self.detail:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['detail'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> HTTPValidationError:
|
||||
"""Create an instance of HTTPValidationError from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return HTTPValidationError.parse_obj(obj)
|
||||
|
||||
_obj = HTTPValidationError.parse_obj({
|
||||
"detail": [ValidationError.from_dict(_item) for _item in obj.get("detail")] if obj.get("detail") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
74
pkgs/clan-cli/tests/openapi_client/models/machine.py
Normal file
74
pkgs/clan-cli/tests/openapi_client/models/machine.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
|
||||
from pydantic import BaseModel, Field, StrictStr
|
||||
from openapi_client.models.status import Status
|
||||
|
||||
class Machine(BaseModel):
|
||||
"""
|
||||
Machine
|
||||
"""
|
||||
name: StrictStr = Field(...)
|
||||
status: Status = Field(...)
|
||||
__properties = ["name", "status"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Machine:
|
||||
"""Create an instance of Machine from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> Machine:
|
||||
"""Create an instance of Machine from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return Machine.parse_obj(obj)
|
||||
|
||||
_obj = Machine.parse_obj({
|
||||
"name": obj.get("name"),
|
||||
"status": obj.get("status")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
79
pkgs/clan-cli/tests/openapi_client/models/resolution.py
Normal file
79
pkgs/clan-cli/tests/openapi_client/models/resolution.py
Normal file
@@ -0,0 +1,79 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
from datetime import datetime
|
||||
from typing import Any, Dict
|
||||
from pydantic import BaseModel, Field, StrictStr
|
||||
|
||||
class Resolution(BaseModel):
|
||||
"""
|
||||
Resolution
|
||||
"""
|
||||
requester_name: StrictStr = Field(...)
|
||||
requester_did: StrictStr = Field(...)
|
||||
resolved_did: StrictStr = Field(...)
|
||||
other: Dict[str, Any] = Field(...)
|
||||
timestamp: datetime = Field(...)
|
||||
__properties = ["requester_name", "requester_did", "resolved_did", "other", "timestamp"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Resolution:
|
||||
"""Create an instance of Resolution from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> Resolution:
|
||||
"""Create an instance of Resolution from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return Resolution.parse_obj(obj)
|
||||
|
||||
_obj = Resolution.parse_obj({
|
||||
"requester_name": obj.get("requester_name"),
|
||||
"requester_did": obj.get("requester_did"),
|
||||
"resolved_did": obj.get("resolved_did"),
|
||||
"other": obj.get("other"),
|
||||
"timestamp": obj.get("timestamp")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
41
pkgs/clan-cli/tests/openapi_client/models/role.py
Normal file
41
pkgs/clan-cli/tests/openapi_client/models/role.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import json
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
from aenum import Enum, no_arg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Role(str, Enum):
|
||||
"""
|
||||
An enumeration.
|
||||
"""
|
||||
|
||||
"""
|
||||
allowed enum values
|
||||
"""
|
||||
SERVICE_PROSUMER = 'service_prosumer'
|
||||
AP = 'AP'
|
||||
DLG = 'DLG'
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Role:
|
||||
"""Create an instance of Role from a JSON string"""
|
||||
return Role(json.loads(json_str))
|
||||
|
||||
|
||||
95
pkgs/clan-cli/tests/openapi_client/models/service.py
Normal file
95
pkgs/clan-cli/tests/openapi_client/models/service.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import Any, Dict, List
|
||||
from pydantic import BaseModel, Field, StrictStr, conlist
|
||||
from openapi_client.models.service_usage import ServiceUsage
|
||||
|
||||
class Service(BaseModel):
|
||||
"""
|
||||
Service
|
||||
"""
|
||||
uuid: StrictStr = Field(...)
|
||||
service_name: StrictStr = Field(...)
|
||||
service_type: StrictStr = Field(...)
|
||||
endpoint_url: StrictStr = Field(...)
|
||||
other: Dict[str, Any] = Field(...)
|
||||
entity_did: StrictStr = Field(...)
|
||||
status: Dict[str, Any] = Field(...)
|
||||
action: Dict[str, Any] = Field(...)
|
||||
usage: conlist(ServiceUsage) = Field(...)
|
||||
__properties = ["uuid", "service_name", "service_type", "endpoint_url", "other", "entity_did", "status", "action", "usage"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Service:
|
||||
"""Create an instance of Service from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in usage (list)
|
||||
_items = []
|
||||
if self.usage:
|
||||
for _item in self.usage:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['usage'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> Service:
|
||||
"""Create an instance of Service from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return Service.parse_obj(obj)
|
||||
|
||||
_obj = Service.parse_obj({
|
||||
"uuid": obj.get("uuid"),
|
||||
"service_name": obj.get("service_name"),
|
||||
"service_type": obj.get("service_type"),
|
||||
"endpoint_url": obj.get("endpoint_url"),
|
||||
"other": obj.get("other"),
|
||||
"entity_did": obj.get("entity_did"),
|
||||
"status": obj.get("status"),
|
||||
"action": obj.get("action"),
|
||||
"usage": [ServiceUsage.from_dict(_item) for _item in obj.get("usage")] if obj.get("usage") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
95
pkgs/clan-cli/tests/openapi_client/models/service_create.py
Normal file
95
pkgs/clan-cli/tests/openapi_client/models/service_create.py
Normal file
@@ -0,0 +1,95 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import Any, Dict, List
|
||||
from pydantic import BaseModel, Field, StrictStr, conlist
|
||||
from openapi_client.models.service_usage_create import ServiceUsageCreate
|
||||
|
||||
class ServiceCreate(BaseModel):
|
||||
"""
|
||||
ServiceCreate
|
||||
"""
|
||||
uuid: StrictStr = Field(...)
|
||||
service_name: StrictStr = Field(...)
|
||||
service_type: StrictStr = Field(...)
|
||||
endpoint_url: StrictStr = Field(...)
|
||||
other: Dict[str, Any] = Field(...)
|
||||
entity_did: StrictStr = Field(...)
|
||||
status: Dict[str, Any] = Field(...)
|
||||
action: Dict[str, Any] = Field(...)
|
||||
usage: conlist(ServiceUsageCreate) = Field(...)
|
||||
__properties = ["uuid", "service_name", "service_type", "endpoint_url", "other", "entity_did", "status", "action", "usage"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> ServiceCreate:
|
||||
"""Create an instance of ServiceCreate from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in usage (list)
|
||||
_items = []
|
||||
if self.usage:
|
||||
for _item in self.usage:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['usage'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> ServiceCreate:
|
||||
"""Create an instance of ServiceCreate from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return ServiceCreate.parse_obj(obj)
|
||||
|
||||
_obj = ServiceCreate.parse_obj({
|
||||
"uuid": obj.get("uuid"),
|
||||
"service_name": obj.get("service_name"),
|
||||
"service_type": obj.get("service_type"),
|
||||
"endpoint_url": obj.get("endpoint_url"),
|
||||
"other": obj.get("other"),
|
||||
"entity_did": obj.get("entity_did"),
|
||||
"status": obj.get("status"),
|
||||
"action": obj.get("action"),
|
||||
"usage": [ServiceUsageCreate.from_dict(_item) for _item in obj.get("usage")] if obj.get("usage") is not None else None
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
73
pkgs/clan-cli/tests/openapi_client/models/service_usage.py
Normal file
73
pkgs/clan-cli/tests/openapi_client/models/service_usage.py
Normal file
@@ -0,0 +1,73 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
|
||||
from pydantic import BaseModel, Field, StrictInt, StrictStr
|
||||
|
||||
class ServiceUsage(BaseModel):
|
||||
"""
|
||||
ServiceUsage
|
||||
"""
|
||||
times_consumed: StrictInt = Field(...)
|
||||
consumer_entity_did: StrictStr = Field(...)
|
||||
__properties = ["times_consumed", "consumer_entity_did"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> ServiceUsage:
|
||||
"""Create an instance of ServiceUsage from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> ServiceUsage:
|
||||
"""Create an instance of ServiceUsage from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return ServiceUsage.parse_obj(obj)
|
||||
|
||||
_obj = ServiceUsage.parse_obj({
|
||||
"times_consumed": obj.get("times_consumed"),
|
||||
"consumer_entity_did": obj.get("consumer_entity_did")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
|
||||
from pydantic import BaseModel, Field, StrictInt, StrictStr
|
||||
|
||||
class ServiceUsageCreate(BaseModel):
|
||||
"""
|
||||
ServiceUsageCreate
|
||||
"""
|
||||
times_consumed: StrictInt = Field(...)
|
||||
consumer_entity_did: StrictStr = Field(...)
|
||||
__properties = ["times_consumed", "consumer_entity_did"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> ServiceUsageCreate:
|
||||
"""Create an instance of ServiceUsageCreate from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> ServiceUsageCreate:
|
||||
"""Create an instance of ServiceUsageCreate from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return ServiceUsageCreate.parse_obj(obj)
|
||||
|
||||
_obj = ServiceUsageCreate.parse_obj({
|
||||
"times_consumed": obj.get("times_consumed"),
|
||||
"consumer_entity_did": obj.get("consumer_entity_did")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
41
pkgs/clan-cli/tests/openapi_client/models/status.py
Normal file
41
pkgs/clan-cli/tests/openapi_client/models/status.py
Normal file
@@ -0,0 +1,41 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import json
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
from aenum import Enum, no_arg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class Status(str, Enum):
|
||||
"""
|
||||
An enumeration.
|
||||
"""
|
||||
|
||||
"""
|
||||
allowed enum values
|
||||
"""
|
||||
ONLINE = 'online'
|
||||
OFFLINE = 'offline'
|
||||
UNKNOWN = 'unknown'
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Status:
|
||||
"""Create an instance of Status from a JSON string"""
|
||||
return Status(json.loads(json_str))
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
import json
|
||||
|
||||
|
||||
from typing import List
|
||||
from pydantic import BaseModel, Field, StrictStr, conlist
|
||||
from openapi_client.models.validation_error_loc_inner import ValidationErrorLocInner
|
||||
|
||||
class ValidationError(BaseModel):
|
||||
"""
|
||||
ValidationError
|
||||
"""
|
||||
loc: conlist(ValidationErrorLocInner) = Field(...)
|
||||
msg: StrictStr = Field(...)
|
||||
type: StrictStr = Field(...)
|
||||
__properties = ["loc", "msg", "type"]
|
||||
|
||||
class Config:
|
||||
"""Pydantic configuration"""
|
||||
allow_population_by_field_name = True
|
||||
validate_assignment = True
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the model using alias"""
|
||||
return pprint.pformat(self.dict(by_alias=True))
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the model using alias"""
|
||||
return json.dumps(self.to_dict())
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> ValidationError:
|
||||
"""Create an instance of ValidationError from a JSON string"""
|
||||
return cls.from_dict(json.loads(json_str))
|
||||
|
||||
def to_dict(self):
|
||||
"""Returns the dictionary representation of the model using alias"""
|
||||
_dict = self.dict(by_alias=True,
|
||||
exclude={
|
||||
},
|
||||
exclude_none=True)
|
||||
# override the default output from pydantic by calling `to_dict()` of each item in loc (list)
|
||||
_items = []
|
||||
if self.loc:
|
||||
for _item in self.loc:
|
||||
if _item:
|
||||
_items.append(_item.to_dict())
|
||||
_dict['loc'] = _items
|
||||
return _dict
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> ValidationError:
|
||||
"""Create an instance of ValidationError from a dict"""
|
||||
if obj is None:
|
||||
return None
|
||||
|
||||
if not isinstance(obj, dict):
|
||||
return ValidationError.parse_obj(obj)
|
||||
|
||||
_obj = ValidationError.parse_obj({
|
||||
"loc": [ValidationErrorLocInner.from_dict(_item) for _item in obj.get("loc")] if obj.get("loc") is not None else None,
|
||||
"msg": obj.get("msg"),
|
||||
"type": obj.get("type")
|
||||
})
|
||||
return _obj
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
from __future__ import annotations
|
||||
from inspect import getfullargspec
|
||||
import json
|
||||
import pprint
|
||||
import re # noqa: F401
|
||||
|
||||
from typing import Optional
|
||||
from pydantic import BaseModel, Field, StrictInt, StrictStr, ValidationError, validator
|
||||
from typing import Union, Any, List, TYPE_CHECKING
|
||||
from pydantic import StrictStr, Field
|
||||
|
||||
VALIDATIONERRORLOCINNER_ANY_OF_SCHEMAS = ["int", "str"]
|
||||
|
||||
class ValidationErrorLocInner(BaseModel):
|
||||
"""
|
||||
ValidationErrorLocInner
|
||||
"""
|
||||
|
||||
# data type: str
|
||||
anyof_schema_1_validator: Optional[StrictStr] = None
|
||||
# data type: int
|
||||
anyof_schema_2_validator: Optional[StrictInt] = None
|
||||
if TYPE_CHECKING:
|
||||
actual_instance: Union[int, str]
|
||||
else:
|
||||
actual_instance: Any
|
||||
any_of_schemas: List[str] = Field(VALIDATIONERRORLOCINNER_ANY_OF_SCHEMAS, const=True)
|
||||
|
||||
class Config:
|
||||
validate_assignment = True
|
||||
|
||||
def __init__(self, *args, **kwargs) -> None:
|
||||
if args:
|
||||
if len(args) > 1:
|
||||
raise ValueError("If a position argument is used, only 1 is allowed to set `actual_instance`")
|
||||
if kwargs:
|
||||
raise ValueError("If a position argument is used, keyword arguments cannot be used.")
|
||||
super().__init__(actual_instance=args[0])
|
||||
else:
|
||||
super().__init__(**kwargs)
|
||||
|
||||
@validator('actual_instance')
|
||||
def actual_instance_must_validate_anyof(cls, v):
|
||||
instance = ValidationErrorLocInner.construct()
|
||||
error_messages = []
|
||||
# validate data type: str
|
||||
try:
|
||||
instance.anyof_schema_1_validator = v
|
||||
return v
|
||||
except (ValidationError, ValueError) as e:
|
||||
error_messages.append(str(e))
|
||||
# validate data type: int
|
||||
try:
|
||||
instance.anyof_schema_2_validator = v
|
||||
return v
|
||||
except (ValidationError, ValueError) as e:
|
||||
error_messages.append(str(e))
|
||||
if error_messages:
|
||||
# no match
|
||||
raise ValueError("No match found when setting the actual_instance in ValidationErrorLocInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages))
|
||||
else:
|
||||
return v
|
||||
|
||||
@classmethod
|
||||
def from_dict(cls, obj: dict) -> ValidationErrorLocInner:
|
||||
return cls.from_json(json.dumps(obj))
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> ValidationErrorLocInner:
|
||||
"""Returns the object represented by the json string"""
|
||||
instance = ValidationErrorLocInner.construct()
|
||||
error_messages = []
|
||||
# deserialize data into str
|
||||
try:
|
||||
# validation
|
||||
instance.anyof_schema_1_validator = json.loads(json_str)
|
||||
# assign value to actual_instance
|
||||
instance.actual_instance = instance.anyof_schema_1_validator
|
||||
return instance
|
||||
except (ValidationError, ValueError) as e:
|
||||
error_messages.append(str(e))
|
||||
# deserialize data into int
|
||||
try:
|
||||
# validation
|
||||
instance.anyof_schema_2_validator = json.loads(json_str)
|
||||
# assign value to actual_instance
|
||||
instance.actual_instance = instance.anyof_schema_2_validator
|
||||
return instance
|
||||
except (ValidationError, ValueError) as e:
|
||||
error_messages.append(str(e))
|
||||
|
||||
if error_messages:
|
||||
# no match
|
||||
raise ValueError("No match found when deserializing the JSON string into ValidationErrorLocInner with anyOf schemas: int, str. Details: " + ", ".join(error_messages))
|
||||
else:
|
||||
return instance
|
||||
|
||||
def to_json(self) -> str:
|
||||
"""Returns the JSON representation of the actual instance"""
|
||||
if self.actual_instance is None:
|
||||
return "null"
|
||||
|
||||
to_json = getattr(self.actual_instance, "to_json", None)
|
||||
if callable(to_json):
|
||||
return self.actual_instance.to_json()
|
||||
else:
|
||||
return json.dumps(self.actual_instance)
|
||||
|
||||
def to_dict(self) -> dict:
|
||||
"""Returns the dict representation of the actual instance"""
|
||||
if self.actual_instance is None:
|
||||
return "null"
|
||||
|
||||
to_json = getattr(self.actual_instance, "to_json", None)
|
||||
if callable(to_json):
|
||||
return self.actual_instance.to_dict()
|
||||
else:
|
||||
return json.dumps(self.actual_instance)
|
||||
|
||||
def to_str(self) -> str:
|
||||
"""Returns the string representation of the actual instance"""
|
||||
return pprint.pformat(self.dict())
|
||||
|
||||
|
||||
303
pkgs/clan-cli/tests/openapi_client/rest.py
Normal file
303
pkgs/clan-cli/tests/openapi_client/rest.py
Normal file
@@ -0,0 +1,303 @@
|
||||
# coding: utf-8
|
||||
|
||||
"""
|
||||
FastAPI
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
The version of the OpenAPI document: 0.1.0
|
||||
Generated by OpenAPI Generator (https://openapi-generator.tech)
|
||||
|
||||
Do not edit the class manually.
|
||||
""" # noqa: E501
|
||||
|
||||
|
||||
import io
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
import ssl
|
||||
|
||||
from urllib.parse import urlencode, quote_plus
|
||||
import urllib3
|
||||
|
||||
from openapi_client.exceptions import ApiException, UnauthorizedException, ForbiddenException, NotFoundException, ServiceException, ApiValueError, BadRequestException
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RESTResponse(io.IOBase):
|
||||
|
||||
def __init__(self, resp) -> None:
|
||||
self.urllib3_response = resp
|
||||
self.status = resp.status
|
||||
self.reason = resp.reason
|
||||
self.data = resp.data
|
||||
|
||||
def getheaders(self):
|
||||
"""Returns a dictionary of the response headers."""
|
||||
return self.urllib3_response.headers
|
||||
|
||||
def getheader(self, name, default=None):
|
||||
"""Returns a given response header."""
|
||||
return self.urllib3_response.headers.get(name, default)
|
||||
|
||||
|
||||
class RESTClientObject:
|
||||
|
||||
def __init__(self, configuration, pools_size=4, maxsize=None) -> None:
|
||||
# urllib3.PoolManager will pass all kw parameters to connectionpool
|
||||
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/poolmanager.py#L75 # noqa: E501
|
||||
# https://github.com/shazow/urllib3/blob/f9409436f83aeb79fbaf090181cd81b784f1b8ce/urllib3/connectionpool.py#L680 # noqa: E501
|
||||
# maxsize is the number of requests to host that are allowed in parallel # noqa: E501
|
||||
# Custom SSL certificates and client certificates: http://urllib3.readthedocs.io/en/latest/advanced-usage.html # noqa: E501
|
||||
|
||||
# cert_reqs
|
||||
if configuration.verify_ssl:
|
||||
cert_reqs = ssl.CERT_REQUIRED
|
||||
else:
|
||||
cert_reqs = ssl.CERT_NONE
|
||||
|
||||
addition_pool_args = {}
|
||||
if configuration.assert_hostname is not None:
|
||||
addition_pool_args['assert_hostname'] = configuration.assert_hostname # noqa: E501
|
||||
|
||||
if configuration.retries is not None:
|
||||
addition_pool_args['retries'] = configuration.retries
|
||||
|
||||
if configuration.tls_server_name:
|
||||
addition_pool_args['server_hostname'] = configuration.tls_server_name
|
||||
|
||||
|
||||
if configuration.socket_options is not None:
|
||||
addition_pool_args['socket_options'] = configuration.socket_options
|
||||
|
||||
if maxsize is None:
|
||||
if configuration.connection_pool_maxsize is not None:
|
||||
maxsize = configuration.connection_pool_maxsize
|
||||
else:
|
||||
maxsize = 4
|
||||
|
||||
# https pool manager
|
||||
if configuration.proxy:
|
||||
self.pool_manager = urllib3.ProxyManager(
|
||||
num_pools=pools_size,
|
||||
maxsize=maxsize,
|
||||
cert_reqs=cert_reqs,
|
||||
ca_certs=configuration.ssl_ca_cert,
|
||||
cert_file=configuration.cert_file,
|
||||
key_file=configuration.key_file,
|
||||
proxy_url=configuration.proxy,
|
||||
proxy_headers=configuration.proxy_headers,
|
||||
**addition_pool_args
|
||||
)
|
||||
else:
|
||||
self.pool_manager = urllib3.PoolManager(
|
||||
num_pools=pools_size,
|
||||
maxsize=maxsize,
|
||||
cert_reqs=cert_reqs,
|
||||
ca_certs=configuration.ssl_ca_cert,
|
||||
cert_file=configuration.cert_file,
|
||||
key_file=configuration.key_file,
|
||||
**addition_pool_args
|
||||
)
|
||||
|
||||
def request(self, method, url, query_params=None, headers=None,
|
||||
body=None, post_params=None, _preload_content=True,
|
||||
_request_timeout=None):
|
||||
"""Perform requests.
|
||||
|
||||
:param method: http request method
|
||||
:param url: http request url
|
||||
:param query_params: query parameters in the url
|
||||
:param headers: http request headers
|
||||
:param body: request json body, for `application/json`
|
||||
:param post_params: request post parameters,
|
||||
`application/x-www-form-urlencoded`
|
||||
and `multipart/form-data`
|
||||
:param _preload_content: if False, the urllib3.HTTPResponse object will
|
||||
be returned without reading/decoding response
|
||||
data. Default is True.
|
||||
:param _request_timeout: timeout setting for this request. If one
|
||||
number provided, it will be total request
|
||||
timeout. It can also be a pair (tuple) of
|
||||
(connection, read) timeouts.
|
||||
"""
|
||||
method = method.upper()
|
||||
assert method in ['GET', 'HEAD', 'DELETE', 'POST', 'PUT',
|
||||
'PATCH', 'OPTIONS']
|
||||
|
||||
if post_params and body:
|
||||
raise ApiValueError(
|
||||
"body parameter cannot be used with post_params parameter."
|
||||
)
|
||||
|
||||
post_params = post_params or {}
|
||||
headers = headers or {}
|
||||
# url already contains the URL query string
|
||||
# so reset query_params to empty dict
|
||||
query_params = {}
|
||||
|
||||
timeout = None
|
||||
if _request_timeout:
|
||||
if isinstance(_request_timeout, (int,float)): # noqa: E501,F821
|
||||
timeout = urllib3.Timeout(total=_request_timeout)
|
||||
elif (isinstance(_request_timeout, tuple) and
|
||||
len(_request_timeout) == 2):
|
||||
timeout = urllib3.Timeout(
|
||||
connect=_request_timeout[0], read=_request_timeout[1])
|
||||
|
||||
try:
|
||||
# For `POST`, `PUT`, `PATCH`, `OPTIONS`, `DELETE`
|
||||
if method in ['POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE']:
|
||||
|
||||
# no content type provided or payload is json
|
||||
if not headers.get('Content-Type') or re.search('json', headers['Content-Type'], re.IGNORECASE):
|
||||
request_body = None
|
||||
if body is not None:
|
||||
request_body = json.dumps(body)
|
||||
r = self.pool_manager.request(
|
||||
method, url,
|
||||
body=request_body,
|
||||
preload_content=_preload_content,
|
||||
timeout=timeout,
|
||||
headers=headers)
|
||||
elif headers['Content-Type'] == 'application/x-www-form-urlencoded': # noqa: E501
|
||||
r = self.pool_manager.request(
|
||||
method, url,
|
||||
fields=post_params,
|
||||
encode_multipart=False,
|
||||
preload_content=_preload_content,
|
||||
timeout=timeout,
|
||||
headers=headers)
|
||||
elif headers['Content-Type'] == 'multipart/form-data':
|
||||
# must del headers['Content-Type'], or the correct
|
||||
# Content-Type which generated by urllib3 will be
|
||||
# overwritten.
|
||||
del headers['Content-Type']
|
||||
r = self.pool_manager.request(
|
||||
method, url,
|
||||
fields=post_params,
|
||||
encode_multipart=True,
|
||||
preload_content=_preload_content,
|
||||
timeout=timeout,
|
||||
headers=headers)
|
||||
# Pass a `string` parameter directly in the body to support
|
||||
# other content types than Json when `body` argument is
|
||||
# provided in serialized form
|
||||
elif isinstance(body, str) or isinstance(body, bytes):
|
||||
request_body = body
|
||||
r = self.pool_manager.request(
|
||||
method, url,
|
||||
body=request_body,
|
||||
preload_content=_preload_content,
|
||||
timeout=timeout,
|
||||
headers=headers)
|
||||
else:
|
||||
# Cannot generate the request from given parameters
|
||||
msg = """Cannot prepare a request message for provided
|
||||
arguments. Please check that your arguments match
|
||||
declared content type."""
|
||||
raise ApiException(status=0, reason=msg)
|
||||
# For `GET`, `HEAD`
|
||||
else:
|
||||
r = self.pool_manager.request(method, url,
|
||||
fields={},
|
||||
preload_content=_preload_content,
|
||||
timeout=timeout,
|
||||
headers=headers)
|
||||
except urllib3.exceptions.SSLError as e:
|
||||
msg = "{0}\n{1}".format(type(e).__name__, str(e))
|
||||
raise ApiException(status=0, reason=msg)
|
||||
|
||||
if _preload_content:
|
||||
r = RESTResponse(r)
|
||||
|
||||
# log response body
|
||||
logger.debug("response body: %s", r.data)
|
||||
|
||||
if not 200 <= r.status <= 299:
|
||||
if r.status == 400:
|
||||
raise BadRequestException(http_resp=r)
|
||||
|
||||
if r.status == 401:
|
||||
raise UnauthorizedException(http_resp=r)
|
||||
|
||||
if r.status == 403:
|
||||
raise ForbiddenException(http_resp=r)
|
||||
|
||||
if r.status == 404:
|
||||
raise NotFoundException(http_resp=r)
|
||||
|
||||
if 500 <= r.status <= 599:
|
||||
raise ServiceException(http_resp=r)
|
||||
|
||||
raise ApiException(http_resp=r)
|
||||
|
||||
return r
|
||||
|
||||
def get_request(self, url, headers=None, query_params=None, _preload_content=True,
|
||||
_request_timeout=None):
|
||||
return self.request("GET", url,
|
||||
headers=headers,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
query_params=query_params)
|
||||
|
||||
def head_request(self, url, headers=None, query_params=None, _preload_content=True,
|
||||
_request_timeout=None):
|
||||
return self.request("HEAD", url,
|
||||
headers=headers,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
query_params=query_params)
|
||||
|
||||
def options_request(self, url, headers=None, query_params=None, post_params=None,
|
||||
body=None, _preload_content=True, _request_timeout=None):
|
||||
return self.request("OPTIONS", url,
|
||||
headers=headers,
|
||||
query_params=query_params,
|
||||
post_params=post_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
|
||||
def delete_request(self, url, headers=None, query_params=None, body=None,
|
||||
_preload_content=True, _request_timeout=None):
|
||||
return self.request("DELETE", url,
|
||||
headers=headers,
|
||||
query_params=query_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
|
||||
def post_request(self, url, headers=None, query_params=None, post_params=None,
|
||||
body=None, _preload_content=True, _request_timeout=None):
|
||||
return self.request("POST", url,
|
||||
headers=headers,
|
||||
query_params=query_params,
|
||||
post_params=post_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
|
||||
def put_request(self, url, headers=None, query_params=None, post_params=None,
|
||||
body=None, _preload_content=True, _request_timeout=None):
|
||||
return self.request("PUT", url,
|
||||
headers=headers,
|
||||
query_params=query_params,
|
||||
post_params=post_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
|
||||
def patch_request(self, url, headers=None, query_params=None, post_params=None,
|
||||
body=None, _preload_content=True, _request_timeout=None):
|
||||
return self.request("PATCH", url,
|
||||
headers=headers,
|
||||
query_params=query_params,
|
||||
post_params=post_params,
|
||||
_preload_content=_preload_content,
|
||||
_request_timeout=_request_timeout,
|
||||
body=body)
|
||||
185
pkgs/clan-cli/tests/test_db_api.py
Normal file
185
pkgs/clan-cli/tests/test_db_api.py
Normal file
@@ -0,0 +1,185 @@
|
||||
import random
|
||||
import time
|
||||
import uuid
|
||||
|
||||
from openapi_client import ApiClient
|
||||
from openapi_client.api import DefaultApi
|
||||
from openapi_client.api.entities_api import EntitiesApi
|
||||
from openapi_client.api.eventmessages_api import EventmessagesApi
|
||||
from openapi_client.api.services_api import ServicesApi
|
||||
from openapi_client.models import (
|
||||
Entity,
|
||||
EntityCreate,
|
||||
Eventmessage,
|
||||
EventmessageCreate,
|
||||
Machine,
|
||||
Role,
|
||||
ServiceCreate,
|
||||
Status,
|
||||
)
|
||||
|
||||
import clan_cli.config as config
|
||||
|
||||
random.seed(42)
|
||||
|
||||
|
||||
host = config.host
|
||||
port_dlg = config.port_dlg
|
||||
port_ap = config.port_ap
|
||||
port_client_base = config._port_client_base
|
||||
|
||||
num_uuids = 100
|
||||
uuids = [str(uuid.UUID(int=random.getrandbits(128))) for i in range(num_uuids)]
|
||||
|
||||
|
||||
def test_health(api_client: ApiClient) -> None:
|
||||
default = DefaultApi(api_client=api_client)
|
||||
res: Machine = default.health()
|
||||
assert res.status == Status.ONLINE
|
||||
|
||||
|
||||
def create_entities(num: int = 5, role: str = "entity") -> list[EntityCreate]:
|
||||
res = []
|
||||
for i in range(1, num + 1):
|
||||
en = EntityCreate(
|
||||
did=f"did:sov:test:12{i}",
|
||||
name=f"C{i}",
|
||||
ip=f"{host}:{port_client_base+i}",
|
||||
network="255.255.0.0",
|
||||
roles=[Role("service_prosumer")],
|
||||
visible=True,
|
||||
other={},
|
||||
)
|
||||
res.append(en)
|
||||
dlg = EntityCreate(
|
||||
did=f"did:sov:test:{port_dlg}",
|
||||
name="DLG",
|
||||
ip=f"{host}:{port_dlg}",
|
||||
network="255.255.0.0",
|
||||
roles=[Role("DLG")],
|
||||
visible=True,
|
||||
other={},
|
||||
)
|
||||
res.append(dlg)
|
||||
ap = EntityCreate(
|
||||
did=f"did:sov:test:{port_ap}",
|
||||
name="AP",
|
||||
ip=f"{host}:{port_ap}",
|
||||
network="255.255.0.0",
|
||||
roles=[Role("AP")],
|
||||
visible=True,
|
||||
other={},
|
||||
)
|
||||
res.append(ap)
|
||||
return res
|
||||
|
||||
|
||||
def create_service(idx: int, entity: Entity) -> ServiceCreate:
|
||||
idx += 1
|
||||
se = ServiceCreate(
|
||||
uuid=uuids[idx],
|
||||
service_name=f"Carlos Printing{idx}",
|
||||
service_type="3D Printing",
|
||||
endpoint_url=f"http://{entity.ip}/v1/print_daemon{idx}",
|
||||
status={"data": ["draft", "registered"]},
|
||||
other={},
|
||||
action={
|
||||
"data": [
|
||||
{
|
||||
"name": "register",
|
||||
"endpoint": f"http://{entity.ip}/v1/print_daemon{idx}/register",
|
||||
},
|
||||
{
|
||||
"name": "deregister",
|
||||
"endpoint": f"http://{entity.ip}/v1/print_daemon{idx}/deregister",
|
||||
},
|
||||
]
|
||||
},
|
||||
entity_did=entity.did,
|
||||
usage=[{"times_consumed": 2, "consumer_entity_did": "did:sov:test:120"}],
|
||||
)
|
||||
|
||||
return se
|
||||
|
||||
|
||||
def test_create_entities(api_client: ApiClient) -> None:
|
||||
api = EntitiesApi(api_client=api_client)
|
||||
|
||||
for own_entity in create_entities():
|
||||
res: Entity = api.create_entity(own_entity)
|
||||
assert res.did == own_entity.did
|
||||
assert res.attached is False
|
||||
|
||||
|
||||
def test_create_services(api_client: ApiClient) -> None:
|
||||
sapi = ServicesApi(api_client=api_client)
|
||||
eapi = EntitiesApi(api_client=api_client)
|
||||
for midx, entity in enumerate(eapi.get_entity_by_roles([Role("service_prosumer")])):
|
||||
service_obj = create_service(midx, entity)
|
||||
service = sapi.create_service(service_obj)
|
||||
assert service.uuid == service_obj.uuid
|
||||
|
||||
|
||||
random.seed(77)
|
||||
|
||||
|
||||
def create_eventmessages(num: int = 4) -> list[EventmessageCreate]:
|
||||
res = []
|
||||
starttime = int(time.time())
|
||||
for i2 in range(1, num + 1):
|
||||
group_id = i2 % 5 + random.getrandbits(6) + 1
|
||||
em_req_send = EventmessageCreate(
|
||||
timestamp=starttime + i2 * 10,
|
||||
group=i2 % 5,
|
||||
group_id=group_id,
|
||||
msg_type=1,
|
||||
src_did=f"did:sov:test:12{i2}",
|
||||
des_did=f"did:sov:test:12{i2+1}",
|
||||
msg={},
|
||||
)
|
||||
res.append(em_req_send)
|
||||
em_req_rec = EventmessageCreate(
|
||||
timestamp=starttime + (i2 * 10) + 2,
|
||||
group=i2 % 5,
|
||||
group_id=group_id,
|
||||
msg_type=2,
|
||||
src_did=f"did:sov:test:12{i2}",
|
||||
des_did=f"did:sov:test:12{i2+1}",
|
||||
msg={},
|
||||
)
|
||||
res.append(em_req_rec)
|
||||
group_id = i2 % 5 + random.getrandbits(6)
|
||||
em_res_send = EventmessageCreate(
|
||||
timestamp=starttime + i2 * 10 + 4,
|
||||
group=i2 % 5,
|
||||
group_id=group_id,
|
||||
msg_type=3,
|
||||
src_did=f"did:sov:test:12{i2+1}",
|
||||
des_did=f"did:sov:test:12{i2}",
|
||||
msg={},
|
||||
)
|
||||
res.append(em_res_send)
|
||||
em_res_rec = EventmessageCreate(
|
||||
timestamp=starttime + (i2 * 10) + 8,
|
||||
group=i2 % 5,
|
||||
group_id=group_id,
|
||||
msg_type=4,
|
||||
src_did=f"did:sov:test:12{i2+1}",
|
||||
des_did=f"did:sov:test:12{i2}",
|
||||
msg={},
|
||||
)
|
||||
res.append(em_res_rec)
|
||||
return res
|
||||
|
||||
|
||||
def test_create_eventmessages(api_client: ApiClient) -> None:
|
||||
api = EventmessagesApi(api_client=api_client)
|
||||
|
||||
assert api.get_all_eventmessages() is None
|
||||
for idx, own_eventmsg in enumerate(create_eventmessages()):
|
||||
res: Eventmessage = api.create_eventmessage(own_eventmsg)
|
||||
|
||||
assert res.msg == own_eventmsg.msg
|
||||
assert res.src_did == own_eventmsg.src_did
|
||||
assert res.des_did == own_eventmsg.des_did
|
||||
assert {} != api.get_all_eventmessages()
|
||||
48
pkgs/clan-cli/upload_ui_assets.sh
Executable file
48
pkgs/clan-cli/upload_ui_assets.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# shellcheck shell=bash
|
||||
set -euo pipefail
|
||||
|
||||
# GITLAB_TOKEN
|
||||
if [[ -z "${GITLAB_TOKEN:-}" ]]; then
|
||||
cat <<EOF
|
||||
GITLAB_TOKEN environment var is not set. Please generate a new token under
|
||||
https://git.tu-berlin.de/internet-of-services-lab/service-aware-network-front-end/-/settings/access_tokens
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -d)
|
||||
cleanup() { rm -rf "$tmpdir"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
# Create a new ui build
|
||||
nix build '.#ui' --out-link "$tmpdir/result"
|
||||
|
||||
|
||||
tar --transform 's,^\.,assets,' -czvf "$tmpdir/assets.tar.gz" -C "$tmpdir"/result/lib/node_modules/*/out .
|
||||
# upload ui assets to gitlab
|
||||
gitlab_base="https://git.tu-berlin.de/api/v4/projects/internet-of-services-lab%2Fservice-aware-network-front-end"
|
||||
curl --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
|
||||
--upload-file "$tmpdir/assets.tar.gz" \
|
||||
"$gitlab_base/packages/generic/ui-assets/1.0.0/ui-assets.tar.gz"
|
||||
|
||||
|
||||
# write url and hash to ui-assets.nix
|
||||
url="$gitlab_base/packages/generic/ui-assets/1.0.0/ui-assets.tar.gz"
|
||||
PROJECT_DIR=$(git rev-parse --show-toplevel)
|
||||
cat > "$PROJECT_DIR/pkgs/ui/nix/ui-assets.nix" <<EOF
|
||||
{ fetchzip }:
|
||||
fetchzip {
|
||||
url = "$url";
|
||||
sha256 = "$(nix-prefetch-url --unpack $url)";
|
||||
}
|
||||
EOF
|
||||
|
||||
|
||||
cat <<EOF
|
||||
Please commit the changes to ui-assets.nix and push them to the repository.
|
||||
If you want clan webui to use the new ui assets.
|
||||
$ git commit -m "Update ui-assets.nix" "$PROJECT_DIR/pkgs/ui/nix/ui-assets.nix"
|
||||
$ git push
|
||||
EOF
|
||||
@@ -1,43 +1,9 @@
|
||||
{ stdenv
|
||||
, lib
|
||||
, nixVersions
|
||||
, fetchFromGitHub
|
||||
, nlohmann_json
|
||||
, boost
|
||||
, meson
|
||||
, pkg-config
|
||||
, ninja
|
||||
, cmake
|
||||
, clang-tools
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation {
|
||||
pname = "nix-unit";
|
||||
version = "0.1";
|
||||
src = fetchFromGitHub {
|
||||
owner = "adisbladis";
|
||||
repo = "nix-unit";
|
||||
rev = "3ed2378bddad85257fc508a291408f9ed9673d01";
|
||||
sha256 = "sha256-HvMq0TJGYSx37zHm4j2d+JUZx4/6X7xKEt/0DeCiwjQ=";
|
||||
{ callPackage }:
|
||||
let
|
||||
nix-unit-src = builtins.fetchGit {
|
||||
url = "https://github.com/adisbladis/nix-unit";
|
||||
rev = "7e2ee1c70f930b9b65b9fc33c3f3eca0dfae00d1";
|
||||
};
|
||||
buildInputs = [
|
||||
nlohmann_json
|
||||
nixVersions.stable
|
||||
boost
|
||||
];
|
||||
nativeBuildInputs = [
|
||||
meson
|
||||
pkg-config
|
||||
ninja
|
||||
# nlohmann_json can be only discovered via cmake files
|
||||
cmake
|
||||
] ++ (lib.optional stdenv.cc.isClang [ clang-tools ]);
|
||||
in
|
||||
callPackage nix-unit-src { }
|
||||
|
||||
meta = {
|
||||
description = "Nix unit test runner";
|
||||
homepage = "https://github.com/adisbladis/nix-unit";
|
||||
license = lib.licenses.gpl3;
|
||||
maintainers = with lib.maintainers; [ adisbladis ];
|
||||
platforms = lib.platforms.unix;
|
||||
};
|
||||
}
|
||||
|
||||
0
pkgs/node-packages/generate.sh
Executable file → Normal file
0
pkgs/node-packages/generate.sh
Executable file → Normal file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user