Skip to content

Commit

Permalink
feat: graceful shutdown; logging fix; small image-90MB
Browse files Browse the repository at this point in the history
  • Loading branch information
kentbull committed Dec 22, 2024
1 parent 2d54cce commit 3965df3
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 74 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout 🛎️
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Deploy 🚀
uses: JamesIves/github-pages-deploy-action@v4.3.3
uses: JamesIves/github-pages-deploy-action@v4.7.2
with:
branch: gh-pages # The branch the action should deploy to.
folder: static
16 changes: 8 additions & 8 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- name: Set up Python 3.19
uses: actions/setup-python@v2
- uses: actions/checkout@v4
- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version: 3.10.4
python-version: 3.12.2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand All @@ -29,11 +29,11 @@ jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.10.4
uses: actions/setup-python@v2
- uses: actions/checkout@v4
- name: Set up Python 3.12.2
uses: actions/setup-python@v5
with:
python-version: 3.10.4
python-version: 3.12.2
- name: Install dependencies
run: |
python -m pip install --upgrade pip
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ push-all:

.PHONY: build-vlei
build-vlei:
@docker buildx build --platform=linux/amd64 --no-cache -f container/Dockerfile --tag gleif/vlei:latest --tag gleif/vlei:0.1.0 .
@docker buildx build --load --platform=linux/amd64 -f container/Dockerfile --tag gleif/vlei:latest --tag gleif/vlei:0.2.1 .
54 changes: 46 additions & 8 deletions container/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,15 +1,53 @@
FROM python:3.10.4-buster
FROM python:3.12.6-slim AS builder

RUN apt-get update
RUN apt-get install -y ca-certificates
# Install compilation dependencies for Ubuntu including ca-certificates, libffi, and libsodium
RUN apt-get update && apt-get install -y \
build-essential \
libffi-dev \
libsodium-dev \
libssl-dev \
python3-dev \
python3-venv \
python3-pip \
curl

SHELL ["/bin/bash", "-c"]

# Setup Rust for blake3 dependency build
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y

WORKDIR /vLEI

RUN python -m venv venv
ENV PATH=/vLEI/venv/bin:${PATH}
RUN pip install --upgrade pip

COPY requirements.txt setup.py /vLEI/
RUN mkdir /vLEI/src

RUN apt-get install -y libsodium23
# Build vLEI-server
RUN . "$HOME/.cargo/env" && \
pip install -r requirements.txt

# Create smaller runner image by copying over built binary
FROM python:3.12.6-slim AS runner

RUN apt-get update
RUN apt-get install -y libsodium23 curl

# Prevents Python from buffering stdout and stderr, logs to stdout immediately
ENV PYTHONUNBUFFERED=1
# Set default encoding to UTF-8
ENV PYTHONIOENCODING=UTF-8

WORKDIR /usr/local/var/
RUN git clone https://github.com/WebOfTrust/vLEI
WORKDIR /vLEI

COPY --from=builder /vLEI /vLEI
COPY src/ src/
COPY ./schema/acdc /vLEI/schema
COPY ./samples/acdc /vLEI/credentials
COPY ./samples/oobis /vLEI/oobis

ENV PATH=/vLEI/venv/bin:${PATH}

WORKDIR /usr/local/var/vLEI
RUN pip install -r requirements.txt
CMD ["vLEI-server", "-s", "/vLEI/schema", "-c", "/vLEI/credentials", "-o", "/vLEI/oobis"]
48 changes: 24 additions & 24 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from setuptools import find_packages, setup
setup(
name='vlei',
version='0.0.1', # also change in src/vlei/__init__.py
version='0.2.1', # also change in src/vlei/__init__.py
license='Apache Software License 2.0',
description='Verifiable Legal Entity Identifier',
long_description="Verifiable Legal Entity Identifier Schema Generator and Server",
Expand All @@ -51,7 +51,7 @@
'Operating System :: Unix',
'Operating System :: POSIX',
'Operating System :: Microsoft :: Windows',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: Implementation :: CPython',
'Topic :: Utilities',
],
Expand All @@ -61,34 +61,34 @@
'Issue Tracker': 'https://github.com/WebOfTrust/keripy/issues',
},
keywords=[
# eg: 'keyword1', 'keyword2', 'keyword3',
'keri','acdc','vlei'
],
python_requires='>=3.10.4',
python_requires='>=3.12.2',
install_requires=[
'lmdb>=1.2.1',
'pysodium>=0.7.9',
'blake3>=0.2.0',
'msgpack>=1.0.2',
'cbor2>=5.4.1',
'multidict>=5.1.0',
'ordered-set>=4.1.0',
'hio>=0.5.8',
'multicommand>=0.1.1',
'jsonschema>=3.2.0',
'falcon>=3.0.1',
'daemonocle>=1.2.3',
'hjson>=3.0.2',
'PyYaml>=6.0',
'apispec>=5.1.1',
'mnemonic>=0.20',
'keri>=1.0.0',
'lmdb>=1.4.1',
'pysodium>=0.7.17',
'blake3>=0.4.1',
'msgpack>=1.0.8',
'cbor2>=5.6.2',
'multidict>=6.0.5',
'ordered-set>=4.1.0',
'hio==0.6.14',
'multicommand>=1.0.0',
'jsonschema>=4.21.1',
'falcon>=3.1.3',
'daemonocle>=1.2.3',
'hjson>=3.1.0',
'PyYaml>=6.0.2',
'apispec>=6.8.0',
'mnemonic>=0.21',
'keri>=1.2.1',
],
extras_require={
},
tests_require=[
'coverage>=5.5',
'pytest>=6.2.5',
],
'coverage>=7.4.4',
'pytest>=8.1.1',
],
setup_requires=[
],
entry_points={
Expand Down
2 changes: 1 addition & 1 deletion src/vlei/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- encoding: utf-8 -*-

__version__ = '0.1.1' # also change in setup.py
__version__ = '0.2.1' # also change in setup.py

6 changes: 4 additions & 2 deletions src/vlei/app/caching.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
import os

from keri.core import scheming
from keri import help

logger = help.ogler.getLogger()

def cacheSchema(path, d):
for root, dirs, files in os.walk(path):
Expand All @@ -16,7 +18,7 @@ def cacheSchema(path, d):
with open(os.path.join(root, file), 'r') as f:
ked = json.load(f)
schemer = scheming.Schemer(sed=ked)
print(f"caching schema {schemer.said}")
logger.info(f"caching schema {schemer.said}")
d[schemer.said] = schemer.raw

return d
Expand All @@ -28,7 +30,7 @@ def cacheCredential(path, d):
if file.endswith('-acdc.cesr'):
with open(os.path.join(root, file), 'r') as f:
said = file.removesuffix('-acdc.cesr')
print(f"caching credential {said}")
logger.info(f"caching credential {said}")
d[said] = f.read()

return d
Expand Down
2 changes: 1 addition & 1 deletion src/vlei/app/generating.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from keri.core import coring


def populateSAIDS(d: dict, idage: str = coring.Ids.dollar, code: str = coring.MtrDex.Blake3_256):
def populateSAIDS(d: dict, idage: str = coring.Saids.dollar, code: str = coring.MtrDex.Blake3_256):
if 'properties' in d:
props = d['properties']

Expand Down
35 changes: 29 additions & 6 deletions src/vlei/app/serving.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,34 @@
vLEI.serving module
"""
import os
from pathlib import Path
import falcon
from hio.core import http

from keri import help

from vlei.app import caching

logger = help.ogler.getLogger()

class SchemaEnd:
class ACDCMaterialEnd:
"""Returns ACDC credential schemas or ACDC credentials on HTTP GET"""

def __init__(self, schemaDir, credDir):
self.schemaCache = caching.cacheSchema(schemaDir, dict())
if len(self.schemaCache) == 0:
logger.error(f"WARNING: No schemas found in schemaDir {schemaDir}")

self.credentialCache = caching.cacheCredential(credDir, dict())
if len(self.credentialCache) == 0:
logger.error(f"WARNING: No credentials found in credDir {credDir}")

def on_get(self, _, rep, said):
"""
Returns either ACDC JSON Schema or ACDC Credential if the key (SAID) is in the cache.
The cache is loaded on startup with the -s (schema) and -c (credentials) arguments.
"""
if said in self.schemaCache:
data = self.schemaCache[said]

Expand All @@ -34,20 +48,29 @@ def on_get(self, _, rep, said):
return


class WellknownEnd:
class WellKnownEnd:
"""
Returns well known OOBI URLs on HTTP GET in the Location header as a HTTP 301 redirect.
The well known OOBI URLs are text files stored in the directory specified by the oobiDir argument.
The file name is the alias of the well known OOBI and the content of the file is the URL.
"""
def __init__(self, oobiDir):
self.oobiDir = oobiDir
for root, dirs, files in os.walk(oobiDir):
for file in files:
p = Path(oobiDir, file)
url = p.open().read()
logger.info(f"serving well known {file}: {url}")

def on_get(self, req, rep, alias):
"""
Returns the URL of the well known OOBI in the Location header as a HTTP 301 redirect
Parameters:
req (Request): HTTP Request Object
rep (Response): HTTP Response Object
alias (str): Alias of Well-Known OOBI
"""

p = Path(self.oobiDir, alias)
if not p.exists():
raise falcon.HTTPBadRequest(title="Unknown well known")
Expand All @@ -60,8 +83,8 @@ def loadEnds(app, schemaDir, credDir, oobiDir):
sink = http.serving.StaticSink(staticDirPath="./static")
app.add_sink(sink, prefix=sink.DefaultStaticSinkBasePath)

schemaEnd = SchemaEnd(schemaDir=schemaDir, credDir=credDir)
schemaEnd = ACDCMaterialEnd(schemaDir=schemaDir, credDir=credDir)
app.add_route("/oobi/{said}", schemaEnd)

wellknownEnd = WellknownEnd(oobiDir)
wellknownEnd = WellKnownEnd(oobiDir)
app.add_route("/.well-known/keri/oobi/{alias}", wellknownEnd)
19 changes: 10 additions & 9 deletions src/vlei/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
import os
from pathlib import Path

from keri.core import scheming, coring
from keri.core import coring, scheming

from vlei.app import generating


Expand All @@ -23,43 +24,43 @@ def main():
# legal entity -> qvi edge
p = f'{path}/../../schema/acdc/legal-entity-vLEI-credential.json'
le = __load(p)
le['properties']['e']['oneOf'][1]['properties']['qvi']["properties"]['s']['const'] = qvi[coring.Ids.dollar]
le['properties']['e']['oneOf'][1]['properties']['qvi']["properties"]['s']['const'] = qvi[coring.Saids.dollar]
le = generating.populateSAIDS(le)
__save(p, le)

# oor auth -> le edge
p = f'{path}/../../schema/acdc/oor-authorization-vlei-credential.json'
oorAuth = __load(p)
oorAuth['properties']['e']['oneOf'][1]['properties']['le']["properties"]['s']['const'] = le[coring.Ids.dollar]
oorAuth['properties']['e']['oneOf'][1]['properties']['le']["properties"]['s']['const'] = le[coring.Saids.dollar]
oorAuth = generating.populateSAIDS(oorAuth)
__save(p, oorAuth)

# oor -> oor auth edge
p = f'{path}/../../schema/acdc/legal-entity-official-organizational-role-vLEI-credential.json'
oor = __load(p)
oor['properties']['e']['oneOf'][1]['properties']['auth']["properties"]['s']['const'] = oorAuth[coring.Ids.dollar]
oor['properties']['e']['oneOf'][1]['properties']['auth']["properties"]['s']['const'] = oorAuth[coring.Saids.dollar]
oor = generating.populateSAIDS(oor)
__save(p, oor)

# ecr auth -> le edge
p = f'{path}/../../schema/acdc/ecr-authorization-vlei-credential.json'
ecrAuth = __load(p)
ecrAuth['properties']['e']['oneOf'][1]['properties']['le']["properties"]['s']['const'] = le[coring.Ids.dollar]
ecrAuth['properties']['e']['oneOf'][1]['properties']['le']["properties"]['s']['const'] = le[coring.Saids.dollar]
ecrAuth = generating.populateSAIDS(ecrAuth)
__save(p, ecrAuth)

# ecr -> ecr auth edge and le edge
p = f'{path}/../../schema/acdc/legal-entity-engagement-context-role-vLEI-credential.json'
ecr = __load(p)
ecr['properties']['e']['oneOf'][1]['properties']['auth']["properties"]['s']['const'] = ecrAuth[coring.Ids.dollar]
ecr['properties']['e']['oneOf'][2]['properties']['le']["properties"]['s']['const'] = le[coring.Ids.dollar]
ecr['properties']['e']['oneOf'][1]['properties']['auth']["properties"]['s']['const'] = ecrAuth[coring.Saids.dollar]
ecr['properties']['e']['oneOf'][2]['properties']['le']["properties"]['s']['const'] = le[coring.Saids.dollar]
ecr = generating.populateSAIDS(ecr)
__save(p, ecr)

p = f'{path}/../../schema/acdc/verifiable-ixbrl-report-attestation.json'
vira = __load(p)
vira['properties']['e']['oneOf'][0]['properties']['oor']["properties"]['s']['const'] = oor[coring.Ids.dollar]
vira['properties']['e']['oneOf'][1]['properties']['ecr']["properties"]['s']['const'] = ecr[coring.Ids.dollar]
vira['properties']['e']['oneOf'][0]['properties']['oor']["properties"]['s']['const'] = oor[coring.Saids.dollar]
vira['properties']['e']['oneOf'][1]['properties']['ecr']["properties"]['s']['const'] = ecr[coring.Saids.dollar]
vira = generating.populateSAIDS(vira)
__save(p, vira)

Expand Down
Loading

0 comments on commit 3965df3

Please sign in to comment.