Skip to content

Commit

Permalink
docker setup, restapi draft
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelHaussmann committed Apr 11, 2023
1 parent 6d722b7 commit 2b2f0c9
Show file tree
Hide file tree
Showing 6 changed files with 168 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
*.pyc
**__pycache__**
/spil_hamlet_conf/data/testing/SPIL_PROJECTS/**
/spil_hamlet_conf/data/caches/**
**/wip/**
*_secret.py
.git*
21 changes: 21 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#
version: '0.1.1'
services:
restapi:
image: spil/spil
build:
dockerfile: ./spil_server/docker/Dockerfile
restart: on-failure
ports:
- "80:80"

volumes:
- ./spil_hamlet_conf:/spil_conf

# for development: edit the config will reload the app
environment:
- WATCHFILES_FORCE_POLLING=true

# development options for config hot reload.
command: ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "80", "--reload", "--reload-dir", "/spil_conf"]
# https://www.uvicorn.org/settings/
43 changes: 43 additions & 0 deletions spil_server/client_server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Spil network deployment

Client / Server deployment of Spil is still experimental, and work in progress.

## Server side Spil

A fastapi powered Spil REST API is currently under development.

It allows access to the Crud interface via a rest api.
- /find/{config}/{sid}
- /get/{config}/{sid}
- /write/{config}/{sid}

## Client Side Spil

A FindInSpilRest Finder is also in development.

It is able to consume the Spil rest API.
This Finder can replace any other finder, and be used without any change in the code.


## Client-Server

Spil can run both on client and server
With a server instance, serving the rest API.
And a client instance, consuming the rest API, for example used by the UI.

To make this happen clients and servers just need to use different configs.

Finders are interchangeable and connectable.
The spil_data_conf defines which Finder is used for which data type.

#### Connectable Finders

Some Finders call or use other Finders.
For example:
- FindInAll
Calls do_find on other finders, depending on a config.
- FindInCache
Caches the result of other Finders
- FindInSpilRest
Calls the Spil Rest API, which in turn calls Finders.

27 changes: 27 additions & 0 deletions spil_server/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Must be built from spils' repo root folder
# Build: docker build -t spil/spil -f spil_server/docker/Dockerfile .
# Run with python: docker run -ti spil/spil python

#FROM python:3.11
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7

COPY ./spil_server/docker/requirements.txt /spil/requirements.txt
RUN pip install --no-cache-dir --upgrade -r /spil/requirements.txt

# spil will contain spil
COPY ./spil /spil/spil

# This is a placeholder for a later custom config (see docker-compose.yml)
RUN mkdir /spil_conf
ENV PYTHONPATH="${PYTHONPATH}:/spil:/spil_conf"

# spil_hamlet_conf contains the spil demo config
COPY ./spil_hamlet_conf /spil/spil_hamlet_conf

# Init test data
# PYTHONDONTWRITEBYTECODE avoids to have __pycache__ in the Image
RUN export PYTHONDONTWRITEBYTECODE=1 && python -c "import spil;import hamlet_scripts.save_examples_to_mock_fs as mfs;mfs.run()"

# App will contain the fastapi app
# Starting app:main.py is already included in the base docker image (tiangolo/uvicorn-gunicorn-fastapi)
COPY ./spil_server/fastapi/app /app
5 changes: 5 additions & 0 deletions spil_server/docker/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Fileseq
future
logzero
codetiming
typing-extensions
65 changes: 65 additions & 0 deletions spil_server/fastapi/app/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"""
uvicorn main:app --reload
"""
from __future__ import annotations
from typing import Any, Optional, List

from pathlib import Path
from fastapi import FastAPI
from starlette.requests import Request

try:
import spil
except ImportError:
root = Path(__file__).resolve().parent.parent.parent.parent
import sys
sys.path.append(root.as_posix())

from spil import Sid, Finder, Getter, FindInList
from spil import FindInAll, GetFromAll, FindInPaths, GetFromPaths
# from spil_plugins.sg.get_sg import GetFromSG
# from spil_plugins.sg.find_sg import FindInSG
from spil_hamlet_conf.hamlet_scripts.example_sids import sids

app = FastAPI()

finder_config = {
# 'sg': FindInSG(),
'all': FindInAll(),
'paths': FindInPaths(),
'ls': FindInList(list(sids))
}

getter_config = {
# 'sg': GetFromSG(),
'all': GetFromAll(),
'paths': GetFromPaths()
}

@app.get("/find/{config}/{search:path}")
def find(config: str, search: str, request: Request):
finder: Finder | None = finder_config.get(config)
if not finder:
print(f"Finder not found for {config}")
return []

print(f"Finder: {finder}")
search = f"{search}{('?' + str(request.query_params)) if request.query_params else ''}"
print(f"{search}")

for sid in finder.find(search):
yield {"sid": sid.uri}

@app.get("/get/{config}/{search:path}")
def get(config: str, search: str, request: Request):
getter: Getter | None = getter_config.get(config)
if not getter:
print(f"Finder not found for {config}")
return []

print(f"Getter: {getter}")
search = f"{search}{('?' + str(request.query_params)) if request.query_params else ''}"
print(f"{search}")

for data in getter.get(search):
yield data

0 comments on commit 2b2f0c9

Please sign in to comment.