Compare commits
7 Commits
master
...
bvander/fl
Author | SHA1 | Date | |
---|---|---|---|
e8f50d99a8 | |||
d1f092b1a4 | |||
0cd68939ba | |||
d31c29b607 | |||
0ba87bcb9e | |||
9092d2667c | |||
b3405f67dd |
2
.gitignore
vendored
2
.gitignore
vendored
@ -12,4 +12,6 @@ build/
|
|||||||
**/.nyc_output
|
**/.nyc_output
|
||||||
**/coverage
|
**/coverage
|
||||||
**/.venv
|
**/.venv
|
||||||
|
**/venv
|
||||||
|
**/dist
|
||||||
.idea
|
.idea
|
||||||
|
@ -11,4 +11,4 @@ include:
|
|||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
- test
|
- test
|
||||||
- release
|
- publish
|
||||||
|
@ -1,34 +0,0 @@
|
|||||||
# The solc image messes up the alpine environment, so we have to go all over again
|
|
||||||
FROM python:3.8.6-slim-buster
|
|
||||||
|
|
||||||
LABEL authors="Louis Holbrook <dev@holbrook.no> 0826EDA1702D1E87C6E2875121D2E7BB88C2A746"
|
|
||||||
LABEL spdx-license-identifier="GPL-3.0-or-later"
|
|
||||||
LABEL description="Base layer for buiding development images for the cic component suite"
|
|
||||||
|
|
||||||
RUN apt-get update && \
|
|
||||||
apt-get install -y git gcc g++ libpq-dev && \
|
|
||||||
apt-get install -y vim gawk jq telnet openssl iputils-ping curl wget gnupg socat bash procps make python2 postgresql-client
|
|
||||||
|
|
||||||
|
|
||||||
RUN echo installing nodejs tooling
|
|
||||||
|
|
||||||
COPY ./dev/nvm.sh /root/
|
|
||||||
|
|
||||||
# Install nvm with node and npm
|
|
||||||
# https://stackoverflow.com/questions/25899912/how-to-install-nvm-in-docker
|
|
||||||
ENV NVM_DIR /root/.nvm
|
|
||||||
ENV NODE_VERSION 15.3.0
|
|
||||||
ENV BANCOR_NODE_VERSION 10.16.0
|
|
||||||
|
|
||||||
RUN wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash \
|
|
||||||
&& . $NVM_DIR/nvm.sh \
|
|
||||||
&& nvm install $NODE_VERSION \
|
|
||||||
&& nvm alias default $NODE_VERSION \
|
|
||||||
&& nvm use $NODE_VERSION \
|
|
||||||
# So many ridiculously stupid issues with node in docker that take oceans of absolutely wasted time to resolve
|
|
||||||
# owner of these files is "1001" by default - wtf
|
|
||||||
&& chown -R root:root "$NVM_DIR/versions/node/v$NODE_VERSION"
|
|
||||||
|
|
||||||
ENV NODE_PATH $NVM_DIR/versions/node//v$NODE_VERSION/lib/node_modules
|
|
||||||
ENV PATH $NVM_DIR/versions/node//v$NODE_VERSION/bin:$PATH
|
|
||||||
|
|
@ -1 +0,0 @@
|
|||||||
## this is an example base image if we wanted one for all the other apps. Its just OS level things
|
|
7
apps/cic-base/.gitignore
vendored
Normal file
7
apps/cic-base/.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
gmon.out
|
||||||
|
__pycache__
|
||||||
|
*.pyc
|
||||||
|
inc.sh
|
||||||
|
*.egg-info
|
||||||
|
build/
|
||||||
|
dist/
|
20
apps/cic-base/.gitlab-ci.yml
Normal file
20
apps/cic-base/.gitlab-ci.yml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
.cic_base_variables:
|
||||||
|
variables:
|
||||||
|
APP_NAME: cic-base
|
||||||
|
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile
|
||||||
|
|
||||||
|
.cic_base_changes_target:
|
||||||
|
rules:
|
||||||
|
- changes:
|
||||||
|
- $CONTEXT/$APP_NAME/*
|
||||||
|
|
||||||
|
build-mr-cic-base:
|
||||||
|
extends:
|
||||||
|
- .cic_base_changes_target
|
||||||
|
- .py_build_merge_request
|
||||||
|
- .cic_base_variables
|
||||||
|
|
||||||
|
publish_python:
|
||||||
|
extends:
|
||||||
|
- .publish_python
|
||||||
|
- .cic_base_variables
|
1
apps/cic-base/MANIFEST.in
Normal file
1
apps/cic-base/MANIFEST.in
Normal file
@ -0,0 +1 @@
|
|||||||
|
include *requirements.txt
|
8
apps/cic-base/cic_base/__init__.py
Normal file
8
apps/cic-base/cic_base/__init__.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#from . import (
|
||||||
|
# config,
|
||||||
|
# argparse,
|
||||||
|
# rpc,
|
||||||
|
# signer,
|
||||||
|
# log,
|
||||||
|
# version,
|
||||||
|
# )
|
87
apps/cic-base/cic_base/argparse.py
Normal file
87
apps/cic-base/cic_base/argparse.py
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from xdg.BaseDirectory import (
|
||||||
|
xdg_config_dirs,
|
||||||
|
load_first_config,
|
||||||
|
)
|
||||||
|
|
||||||
|
logg = logging.getLogger(__file__)
|
||||||
|
|
||||||
|
fallback_config_path = '/usr/local/etc'
|
||||||
|
xdg_config_dirs += [fallback_config_path]
|
||||||
|
default_config_dir = load_first_config('cic')
|
||||||
|
if default_config_dir == None:
|
||||||
|
default_config_dir = os.path.join('.', '.cic')
|
||||||
|
env_config_dir = os.environ.get('CONFINI_DIR', default_config_dir)
|
||||||
|
|
||||||
|
full_template = {
|
||||||
|
# (long arg and key name, short var, type, default, help,)
|
||||||
|
'provider': ('p', str, None, 'RPC provider url',),
|
||||||
|
'registry_address': ('r', str, None, 'CIC registry address',),
|
||||||
|
'keystore_file': ('y', str, None, 'Keystore file',),
|
||||||
|
'config_dir': ('c', str, env_config_dir, 'Configuration directory',),
|
||||||
|
'queue': ('q', str, 'cic-eth', 'Celery task queue',),
|
||||||
|
'chain_spec': ('i', str, None, 'Chain spec string',),
|
||||||
|
'env_prefix': (None, str, os.environ.get('CONFINI_ENV_PREFIX'), 'Environment prefix for variables to overwrite configuration',),
|
||||||
|
}
|
||||||
|
|
||||||
|
default_include_args = [
|
||||||
|
'config_dir',
|
||||||
|
'provider',
|
||||||
|
'env_prefix',
|
||||||
|
]
|
||||||
|
|
||||||
|
sub = None
|
||||||
|
|
||||||
|
def create(caller_dir, include_args=default_include_args):
|
||||||
|
|
||||||
|
argparser = argparse.ArgumentParser()
|
||||||
|
|
||||||
|
for k in include_args:
|
||||||
|
a = full_template[k]
|
||||||
|
long_flag = '--' + k.replace('_', '-')
|
||||||
|
short_flag = None
|
||||||
|
dest = None
|
||||||
|
if a[0] != None:
|
||||||
|
short_flag = '-' + a[0]
|
||||||
|
dest = a[0]
|
||||||
|
else:
|
||||||
|
dest = k
|
||||||
|
default = a[2]
|
||||||
|
if default == None and k == 'config_dir':
|
||||||
|
default = os.path.join(os.getcwd(), 'config')
|
||||||
|
|
||||||
|
if short_flag == None:
|
||||||
|
argparser.add_argument(long_flag, dest=dest, type=a[1], default=default, help=a[3])
|
||||||
|
else:
|
||||||
|
argparser.add_argument(short_flag, long_flag, dest=dest, type=a[1], default=default, help=a[3])
|
||||||
|
|
||||||
|
argparser.add_argument('-v', action='store_true', help='Be verbose')
|
||||||
|
argparser.add_argument('-vv', action='store_true', help='Be more verbose')
|
||||||
|
|
||||||
|
return argparser
|
||||||
|
|
||||||
|
|
||||||
|
def add(argparser, processor, name, description=None):
|
||||||
|
processor(argparser)
|
||||||
|
|
||||||
|
return argparser
|
||||||
|
|
||||||
|
|
||||||
|
def parse(argparser, logger=None):
|
||||||
|
|
||||||
|
args = argparser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
|
# handle logging input
|
||||||
|
if logger != None:
|
||||||
|
if args.vv:
|
||||||
|
logger.setLevel(logging.DEBUG)
|
||||||
|
elif args.v:
|
||||||
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
|
return args
|
52
apps/cic-base/cic_base/config.py
Normal file
52
apps/cic-base/cic_base/config.py
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
import confini
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from .error import ConfigError
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
default_arg_overrides = {
|
||||||
|
'p': 'ETH_PROVIDER',
|
||||||
|
'i': 'CIC_CHAIN_SPEC',
|
||||||
|
'r': 'CIC_REGISTRY_ADDRESS',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def override(config, override_dict, label):
|
||||||
|
config.dict_override(override_dict, label)
|
||||||
|
config.validate()
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def create(config_dir, args, env_prefix=None, arg_overrides=default_arg_overrides):
|
||||||
|
# handle config input
|
||||||
|
config = None
|
||||||
|
try:
|
||||||
|
config = confini.Config(config_dir, env_prefix)
|
||||||
|
except OSError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if config == None:
|
||||||
|
raise ConfigError('directory {} not found'.format(config_dir))
|
||||||
|
|
||||||
|
config.process()
|
||||||
|
if arg_overrides != None and args != None:
|
||||||
|
override_dict = {}
|
||||||
|
for k in arg_overrides:
|
||||||
|
v = getattr(args, k)
|
||||||
|
if v != None:
|
||||||
|
override_dict[arg_overrides[k]] = v
|
||||||
|
config = override(config, override_dict, 'args')
|
||||||
|
else:
|
||||||
|
config.validate()
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
|
||||||
|
def log(config):
|
||||||
|
logg.debug('config loaded:\n{}'.format(config))
|
2
apps/cic-base/cic_base/error.py
Normal file
2
apps/cic-base/cic_base/error.py
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class ConfigError(Exception):
|
||||||
|
pass
|
18
apps/cic-base/cic_base/log.py
Normal file
18
apps/cic-base/cic_base/log.py
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
|
||||||
|
default_mutelist = [
|
||||||
|
'urllib3',
|
||||||
|
'websockets.protocol',
|
||||||
|
'web3.RequestManager',
|
||||||
|
'web3.providers.WebsocketProvider',
|
||||||
|
'web3.providers.HTTPProvider',
|
||||||
|
]
|
||||||
|
|
||||||
|
def create(name=None, mutelist=default_mutelist):
|
||||||
|
logg = logging.getLogger(name)
|
||||||
|
for m in mutelist:
|
||||||
|
logging.getLogger(m).setLevel(logging.CRITICAL)
|
||||||
|
return logg
|
13
apps/cic-base/cic_base/rpc.py
Normal file
13
apps/cic-base/cic_base/rpc.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# external imports
|
||||||
|
from chainlib.connection import RPCConnection
|
||||||
|
from chainlib.eth.connection import EthUnixSignerConnection
|
||||||
|
from chainlib.eth.sign import (
|
||||||
|
sign_transaction,
|
||||||
|
sign_message,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def setup(chain_spec, evm_provider, signer_provider=None):
|
||||||
|
RPCConnection.register_location(evm_provider, chain_spec, 'default')
|
||||||
|
if signer_provider != None:
|
||||||
|
RPCConnection.register_location(signer_provider, chain_spec, 'signer', constructor=EthUnixSignerConnection)
|
27
apps/cic-base/cic_base/signer.py
Normal file
27
apps/cic-base/cic_base/signer.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
|
||||||
|
from crypto_dev_signer.keystore.dict import DictKeystore
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
keystore = DictKeystore()
|
||||||
|
|
||||||
|
default_passphrase = os.environ.get('ETH_PASSPHRASE', '')
|
||||||
|
|
||||||
|
|
||||||
|
def from_keystore(keyfile, passphrase=default_passphrase):
|
||||||
|
global keystore
|
||||||
|
|
||||||
|
# signer
|
||||||
|
if keyfile == None:
|
||||||
|
raise ValueError('please specify signer keystore file')
|
||||||
|
|
||||||
|
logg.debug('loading keystore file {}'.format(keyfile))
|
||||||
|
address = keystore.import_keystore_file(keyfile, password=passphrase)
|
||||||
|
|
||||||
|
signer = EIP155Signer(keystore)
|
||||||
|
return (address, signer,)
|
122
apps/cic-base/cic_base/sqlalchemy.py
Normal file
122
apps/cic-base/cic_base/sqlalchemy.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
# stanard imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# third-party imports
|
||||||
|
from sqlalchemy import Column, Integer
|
||||||
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy.pool import (
|
||||||
|
StaticPool,
|
||||||
|
QueuePool,
|
||||||
|
AssertionPool,
|
||||||
|
)
|
||||||
|
|
||||||
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
Model = declarative_base(name='Model')
|
||||||
|
|
||||||
|
|
||||||
|
class SessionBase(Model):
|
||||||
|
"""The base object for all SQLAlchemy enabled models. All other models must extend this.
|
||||||
|
"""
|
||||||
|
__abstract__ = True
|
||||||
|
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
|
||||||
|
engine = None
|
||||||
|
"""Database connection engine of the running aplication"""
|
||||||
|
sessionmaker = None
|
||||||
|
"""Factory object responsible for creating sessions from the connection pool"""
|
||||||
|
transactional = True
|
||||||
|
"""Whether the database backend supports query transactions. Should be explicitly set by initialization code"""
|
||||||
|
poolable = True
|
||||||
|
"""Whether the database backend supports connection pools. Should be explicitly set by initialization code"""
|
||||||
|
procedural = True
|
||||||
|
"""Whether the database backend supports stored procedures"""
|
||||||
|
localsessions = {}
|
||||||
|
"""Contains dictionary of sessions initiated by db model components"""
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def create_session():
|
||||||
|
"""Creates a new database session.
|
||||||
|
"""
|
||||||
|
return SessionBase.sessionmaker()
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _set_engine(engine):
|
||||||
|
"""Sets the database engine static property
|
||||||
|
"""
|
||||||
|
SessionBase.engine = engine
|
||||||
|
SessionBase.sessionmaker = sessionmaker(bind=SessionBase.engine)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def connect(dsn, pool_size=8, debug=False):
|
||||||
|
"""Create new database connection engine and connect to database backend.
|
||||||
|
|
||||||
|
:param dsn: DSN string defining connection.
|
||||||
|
:type dsn: str
|
||||||
|
"""
|
||||||
|
e = None
|
||||||
|
if SessionBase.poolable:
|
||||||
|
poolclass = QueuePool
|
||||||
|
if pool_size > 1:
|
||||||
|
e = create_engine(
|
||||||
|
dsn,
|
||||||
|
max_overflow=pool_size*3,
|
||||||
|
pool_pre_ping=True,
|
||||||
|
pool_size=pool_size,
|
||||||
|
pool_recycle=60,
|
||||||
|
poolclass=poolclass,
|
||||||
|
echo=debug,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if debug:
|
||||||
|
poolclass = AssertionPool
|
||||||
|
else:
|
||||||
|
poolclass = StaticPool
|
||||||
|
|
||||||
|
e = create_engine(
|
||||||
|
dsn,
|
||||||
|
poolclass=poolclass,
|
||||||
|
echo=debug,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
e = create_engine(
|
||||||
|
dsn,
|
||||||
|
echo=debug,
|
||||||
|
)
|
||||||
|
|
||||||
|
SessionBase._set_engine(e)
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def disconnect():
|
||||||
|
"""Disconnect from database and free resources.
|
||||||
|
"""
|
||||||
|
SessionBase.engine.dispose()
|
||||||
|
SessionBase.engine = None
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def bind_session(session=None):
|
||||||
|
localsession = session
|
||||||
|
if localsession == None:
|
||||||
|
localsession = SessionBase.create_session()
|
||||||
|
localsession_key = str(id(localsession))
|
||||||
|
logg.debug('creating new session {}'.format(localsession_key))
|
||||||
|
SessionBase.localsessions[localsession_key] = localsession
|
||||||
|
return localsession
|
||||||
|
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def release_session(session=None):
|
||||||
|
session.flush()
|
||||||
|
session_key = str(id(session))
|
||||||
|
if SessionBase.localsessions.get(session_key) != None:
|
||||||
|
logg.debug('destroying session {}'.format(session_key))
|
||||||
|
session.commit()
|
||||||
|
session.close()
|
43
apps/cic-base/cic_base/version.py
Normal file
43
apps/cic-base/cic_base/version.py
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# standard imports
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# third-party imports
|
||||||
|
import semver
|
||||||
|
|
||||||
|
version = (
|
||||||
|
0,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
'beta.22',
|
||||||
|
)
|
||||||
|
|
||||||
|
version_object = semver.VersionInfo(
|
||||||
|
major=version[0],
|
||||||
|
minor=version[1],
|
||||||
|
patch=version[2],
|
||||||
|
prerelease=version[3],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def git_hash():
|
||||||
|
import subprocess
|
||||||
|
git_diff = subprocess.run(['git', 'diff'], capture_output=True)
|
||||||
|
git_hash = subprocess.run(['git', 'rev-parse', 'HEAD'], capture_output=True)
|
||||||
|
git_hash_brief = git_hash.stdout.decode('utf-8')[:8]
|
||||||
|
return git_hash_brief
|
||||||
|
|
||||||
|
version_string = str(version_object)
|
||||||
|
|
||||||
|
try:
|
||||||
|
version_git = git_hash()
|
||||||
|
version_string += '+build.{}'.format(version_git)
|
||||||
|
except FileNotFoundError:
|
||||||
|
time_string_pair = str(time.time()).split('.')
|
||||||
|
version_string += '+build.{}{:<09d}'.format(
|
||||||
|
time_string_pair[0],
|
||||||
|
int(time_string_pair[1]),
|
||||||
|
)
|
||||||
|
|
||||||
|
__version_string__ = version_string
|
26
apps/cic-base/docker/Dockerfile
Normal file
26
apps/cic-base/docker/Dockerfile
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
FROM python:3.8.6-slim-buster
|
||||||
|
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y git gcc g++ libpq-dev && \
|
||||||
|
apt-get install -y vim gawk jq telnet openssl iputils-ping curl wget gnupg socat bash procps make python2 postgresql-client cargo
|
||||||
|
|
||||||
|
WORKDIR /usr/src/cic-base
|
||||||
|
COPY . /usr/src/cic-base/
|
||||||
|
|
||||||
|
#RUN mkdir python
|
||||||
|
#WORKDIR ./python
|
||||||
|
#COPY ./pep503.sh .
|
||||||
|
#RUN pip download --no-cache-dir --extra-index-url https://pip.grassrootseconomics.net:8433 cic-base[full_graph]==0.1.1a6
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
RUN python setup.py bdist_wheel
|
||||||
|
RUN pip download --extra-index-url https://pip.grassrootseconomics.net:8433 dist/$(basename $(ls dist/*))
|
||||||
|
RUN mkdir packages && \
|
||||||
|
cd packages && \
|
||||||
|
bash ../docker/pep503.sh ..
|
||||||
|
|
||||||
|
WORKDIR /usr/src/cic-base/packages
|
||||||
|
|
||||||
|
RUN ls
|
||||||
|
RUN ls ..
|
||||||
|
|
||||||
|
ENTRYPOINT ["python", "-m", "http.server", "8080"]
|
22
apps/cic-base/docker/pep503.sh
Normal file
22
apps/cic-base/docker/pep503.sh
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#!/usr/bin/env
|
||||||
|
|
||||||
|
dest=`pwd`
|
||||||
|
d=$1
|
||||||
|
for df in `find $d -name "*.whl" -type f`; do
|
||||||
|
f=`basename $df`
|
||||||
|
pd=`echo $f | sed -e "s/^\(.*\)-[[:digit:]]*\.[[:digit:]].*$/\1/g" | tr "[:upper:]" "[:lower:]" | tr "_" "-"`
|
||||||
|
mkdir -v $dest/$pd
|
||||||
|
mv -v $df $dest/$pd/
|
||||||
|
done
|
||||||
|
for df in `find $d -name "*.tar.gz" -type f`; do
|
||||||
|
f=`basename $df`
|
||||||
|
pd=`echo $f | sed -e "s/^\(.*\)-[[:digit:]]*\.[[:digit:]].*$/\1/g" | tr "[:upper:]" "[:lower:]" | tr "_" "-"`
|
||||||
|
mkdir -v $dest/$pd
|
||||||
|
mv -v $df $dest/$pd/
|
||||||
|
done
|
||||||
|
for df in `find $d -name "*.zip" -type f`; do
|
||||||
|
f=`basename $df`
|
||||||
|
pd=`echo $f | sed -e "s/^\(.*\)-[[:digit:]]*\.[[:digit:]].*$/\1/g" | tr "[:upper:]" "[:lower:]" | tr "_" "-"`
|
||||||
|
mkdir -v $dest/$pd
|
||||||
|
mv -v $df $dest/$pd/
|
||||||
|
done
|
20
apps/cic-base/examples/cli.py
Normal file
20
apps/cic-base/examples/cli.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import logging
|
||||||
|
import os
|
||||||
|
|
||||||
|
import cic_base.argparse
|
||||||
|
import cic_base.config
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
def more_argparse(argparser):
|
||||||
|
argparser.add_argument('--foo', type=str, help='foo')
|
||||||
|
|
||||||
|
script_dir = os.path.realpath(os.path.dirname(__file__))
|
||||||
|
|
||||||
|
argparser = cic_base.argparse.create(script_dir, include_args=cic_base.argparse.full_template)
|
||||||
|
args = cic_base.argparse.parse(argparser, logger=logg)
|
||||||
|
config = cic_base.config.create(args.c, args, env_prefix=args.env_prefix)
|
||||||
|
|
||||||
|
cic_base.config.log(config)
|
3
apps/cic-base/examples/config/foo.ini
Normal file
3
apps/cic-base/examples/config/foo.ini
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[foo]
|
||||||
|
bar = 42
|
||||||
|
baz = xyzzy
|
98
apps/cic-base/full_graph_requirements.txt
Normal file
98
apps/cic-base/full_graph_requirements.txt
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
africastalking==1.2.3
|
||||||
|
alembic==1.4.2
|
||||||
|
amqp==2.6.1
|
||||||
|
attrs==20.3.0
|
||||||
|
base58==2.1.0
|
||||||
|
bcrypt==3.2.0
|
||||||
|
billiard==3.6.3.0
|
||||||
|
bip-utils==1.4.0
|
||||||
|
bitarray==1.2.2
|
||||||
|
blake2b-py==0.1.4
|
||||||
|
cached-property==1.5.2
|
||||||
|
celery==4.4.7
|
||||||
|
certifi==2020.12.5
|
||||||
|
cffi==1.14.3
|
||||||
|
chainlib==0.0.1a18
|
||||||
|
chainsyncer==0.0.1a18
|
||||||
|
chardet==3.0.4
|
||||||
|
confini==0.3.6rc3
|
||||||
|
contextlib2==0.6.0.post1
|
||||||
|
coverage==5.4
|
||||||
|
cryptography==3.2.1
|
||||||
|
cytoolz==0.11.0
|
||||||
|
ecdsa==0.16.1
|
||||||
|
ecuth==0.4.5a1
|
||||||
|
Faker==4.17.1
|
||||||
|
hexathon==0.0.1a3
|
||||||
|
hexbytes==0.2.1
|
||||||
|
http-hoba-auth==0.2.0
|
||||||
|
idna==2.10
|
||||||
|
iniconfig==1.1.1
|
||||||
|
ipfshttpclient==0.6.1
|
||||||
|
json-rpc==1.13.0
|
||||||
|
jsonschema==3.2.0
|
||||||
|
kombu==4.6.11
|
||||||
|
lru-dict==1.1.7
|
||||||
|
Mako==1.1.3
|
||||||
|
MarkupSafe==1.1.1
|
||||||
|
mirakuru==2.3.0
|
||||||
|
moolb==0.1.1b2
|
||||||
|
more-itertools==8.7.0
|
||||||
|
multiaddr==0.0.9
|
||||||
|
mypy-extensions==0.4.3
|
||||||
|
netaddr==0.8.0
|
||||||
|
packaging==20.9
|
||||||
|
parsimonious==0.8.1
|
||||||
|
phonenumbers==8.12.12
|
||||||
|
pluggy==0.13.1
|
||||||
|
port-for==0.4
|
||||||
|
protobuf==3.15.1
|
||||||
|
psutil==5.8.0
|
||||||
|
psycopg2==2.8.6
|
||||||
|
py==1.9.0
|
||||||
|
py-ecc==4.1.0
|
||||||
|
py-eth==0.1.1
|
||||||
|
pycparser==2.20
|
||||||
|
pycryptodome==3.10.1
|
||||||
|
pyethash==0.1.27
|
||||||
|
pyparsing==2.4.7
|
||||||
|
pyrsistent==0.17.3
|
||||||
|
pysha3==1.0.2
|
||||||
|
pytest==6.0.1
|
||||||
|
pytest-alembic==0.2.5
|
||||||
|
pytest-celery==0.0.0a1
|
||||||
|
pytest-cov==2.10.1
|
||||||
|
pytest-mock==3.3.1
|
||||||
|
pytest-redis==2.0.0
|
||||||
|
python-dateutil==2.8.1
|
||||||
|
python-editor==1.0.4
|
||||||
|
python-gnupg==0.4.6
|
||||||
|
python-i18n==0.3.9
|
||||||
|
pytz==2021.1
|
||||||
|
PyYAML==5.3.1
|
||||||
|
redis==3.5.3
|
||||||
|
requests==2.24.0
|
||||||
|
rlp==2.0.1
|
||||||
|
schema==0.7.4
|
||||||
|
semantic-version==2.8.5
|
||||||
|
semver==2.13.0
|
||||||
|
six==1.15.0
|
||||||
|
sortedcontainers==2.3.0
|
||||||
|
SQLAlchemy==1.3.20
|
||||||
|
sqlparse==0.4.1
|
||||||
|
text-unidecode==1.3
|
||||||
|
tinydb==4.2.0
|
||||||
|
toml==0.10.2
|
||||||
|
toolz==0.11.1
|
||||||
|
transitions==0.8.4
|
||||||
|
trie==2.0.0a5
|
||||||
|
typing-extensions==3.7.4.3
|
||||||
|
urllib3==1.25.11
|
||||||
|
uWSGI==2.0.19.1
|
||||||
|
varint==1.0.2
|
||||||
|
vine==1.3.0
|
||||||
|
vobject==0.9.6.1
|
||||||
|
web3==5.12.2
|
||||||
|
websocket-client==0.57.0
|
||||||
|
websockets==8.1
|
||||||
|
yaml-acl==0.0.1
|
44
apps/cic-base/full_requirements.txt
Normal file
44
apps/cic-base/full_requirements.txt
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
africastalking==1.2.3
|
||||||
|
alembic==1.4.2
|
||||||
|
bcrypt==3.2.0
|
||||||
|
celery==4.4.7
|
||||||
|
confini==0.3.6rc3
|
||||||
|
crypto-dev-signer==0.4.14b4
|
||||||
|
cryptography==3.2.1
|
||||||
|
ecuth==0.4.5a5
|
||||||
|
eth-accounts-index==0.0.11a14
|
||||||
|
eth-address-index==0.1.1a12
|
||||||
|
eth-contract-registry==0.5.5a3
|
||||||
|
erc20-transfer-authorization==0.3.1a7
|
||||||
|
erc20-faucet==0.2.1a5
|
||||||
|
faker==4.17.1
|
||||||
|
http-hoba-auth==0.2.1a2
|
||||||
|
moolb==0.1.1b2
|
||||||
|
phonenumbers==8.12.12
|
||||||
|
psycopg2==2.8.6
|
||||||
|
py-eth~=0.1.1
|
||||||
|
pytest==6.0.1
|
||||||
|
pytest-alembic==0.2.5
|
||||||
|
pytest-celery==0.0.0a1
|
||||||
|
pytest-cov==2.10.1
|
||||||
|
pytest-mock==3.3.1
|
||||||
|
pytest-redis==2.0.0
|
||||||
|
python-i18n==0.3.9
|
||||||
|
PyYAML==5.3.1
|
||||||
|
redis==3.5.3
|
||||||
|
requests==2.24.0
|
||||||
|
semver==2.13.0
|
||||||
|
SQLAlchemy==1.3.20
|
||||||
|
sqlparse==0.4.1
|
||||||
|
tinydb==4.2.0
|
||||||
|
transitions==0.8.4
|
||||||
|
uWSGI==2.0.19.1
|
||||||
|
vobject==0.9.6.1
|
||||||
|
web3==5.12.2
|
||||||
|
websockets==8.1
|
||||||
|
yaml-acl==0.0.1
|
||||||
|
rlp==2.0.1
|
||||||
|
cryptocurrency-cli-tools==0.0.5
|
||||||
|
websocket-client==0.57.0
|
||||||
|
hexathon==0.0.1a7
|
||||||
|
chainsyncer~=0.0.2a5
|
40
apps/cic-base/mac_requirements.txt
Normal file
40
apps/cic-base/mac_requirements.txt
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
confini==0.3.6rc3
|
||||||
|
crypto-dev-signer==0.4.14b1
|
||||||
|
semver==2.13.0
|
||||||
|
SQLAlchemy==1.3.20
|
||||||
|
pyxdg==0.27
|
||||||
|
chainlib==0.0.2a10
|
||||||
|
alembic==1.4.2
|
||||||
|
celery==4.4.7
|
||||||
|
cryptography==3.2.1
|
||||||
|
ecuth==0.4.5a1
|
||||||
|
eth-accounts-index==0.0.11a8
|
||||||
|
eth-address-index==0.1.1a8
|
||||||
|
eth-contract-registry==0.5.4a9
|
||||||
|
erc20-transfer-authorization==0.3.1a4
|
||||||
|
erc20-single-shot-faucet==0.2.0a11
|
||||||
|
faker==4.17.1
|
||||||
|
http-hoba-auth==0.2.0
|
||||||
|
moolb==0.1.1b2
|
||||||
|
phonenumbers==8.12.12
|
||||||
|
psycopg2==2.8.6
|
||||||
|
python-i18n==0.3.9
|
||||||
|
PyYAML==5.3.1
|
||||||
|
redis==3.5.3
|
||||||
|
requests==2.24.0
|
||||||
|
sqlparse==0.4.1
|
||||||
|
transitions==0.8.4
|
||||||
|
uWSGI==2.0.19.1
|
||||||
|
vobject==0.9.6.1
|
||||||
|
web3==5.12.2
|
||||||
|
websockets==8.1
|
||||||
|
yaml-acl==0.0.1
|
||||||
|
rlp==2.0.1
|
||||||
|
cryptocurrency-cli-tools==0.0.4
|
||||||
|
giftable-erc20-token==0.0.8a8
|
||||||
|
websocket-client==0.57.0
|
||||||
|
hexathon==0.0.1a7
|
||||||
|
chainsyncer==0.0.2b1
|
||||||
|
sarafu-faucet==0.0.2a20
|
||||||
|
cic-types==0.1.0a10
|
||||||
|
cic-eth-registry==0.5.4a13
|
9
apps/cic-base/requirements.txt
Normal file
9
apps/cic-base/requirements.txt
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
confini==0.3.6rc3
|
||||||
|
crypto-dev-signer==0.4.14b4
|
||||||
|
semver==2.13.0
|
||||||
|
SQLAlchemy==1.3.20
|
||||||
|
pyxdg==0.27
|
||||||
|
chainlib==0.0.3rc3
|
||||||
|
eth-erc20==0.0.9a4
|
||||||
|
liveness==0.0.1a7
|
||||||
|
requirements-magic~=0.0.1a2
|
35
apps/cic-base/setup.cfg
Normal file
35
apps/cic-base/setup.cfg
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
[metadata]
|
||||||
|
name = cic-base
|
||||||
|
version = attr: cic_base.version.__version_string__
|
||||||
|
description = CIC python base
|
||||||
|
author = Louis Holbrook
|
||||||
|
author_email = dev@holbrook.no
|
||||||
|
url = https://gitlab.com/grassrootseconomics/cic-eth
|
||||||
|
keywords =
|
||||||
|
cic
|
||||||
|
cryptocurrency
|
||||||
|
ethereum
|
||||||
|
classifiers =
|
||||||
|
Programming Language :: Python :: 3
|
||||||
|
Operating System :: OS Independent
|
||||||
|
Development Status :: 3 - Alpha
|
||||||
|
Environment :: No Input/Output (Daemon)
|
||||||
|
Intended Audience :: Developers
|
||||||
|
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
||||||
|
Topic :: Internet
|
||||||
|
# Topic :: Blockchain :: EVM
|
||||||
|
license = GPL3
|
||||||
|
licence_files =
|
||||||
|
LICENSE.txt
|
||||||
|
|
||||||
|
[options]
|
||||||
|
python_requires = >= 3.6
|
||||||
|
packages =
|
||||||
|
cic_base
|
||||||
|
|
||||||
|
|
||||||
|
[options.entry_points]
|
||||||
|
console_scripts =
|
||||||
|
cic-base-audit = cic_base.runnable.audit:main
|
||||||
|
cic-base-merge = cic_base.runnable.merge:main
|
||||||
|
cic-base-update = cic_base.runnable.update:main
|
50
apps/cic-base/setup.py
Normal file
50
apps/cic-base/setup.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
from setuptools import setup
|
||||||
|
import configparser
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import re
|
||||||
|
|
||||||
|
logg = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
re_v = r'[~><=]='
|
||||||
|
def merge(requirements_files, base_dir='.'):
|
||||||
|
|
||||||
|
requirements = {}
|
||||||
|
for r in requirements_files:
|
||||||
|
filepath = os.path.join(base_dir, r)
|
||||||
|
logg.debug('reading {}'.format(filepath))
|
||||||
|
f = open(filepath, 'r')
|
||||||
|
while True:
|
||||||
|
l = f.readline()
|
||||||
|
if l == '':
|
||||||
|
break
|
||||||
|
l = l.rstrip()
|
||||||
|
m = re.split(re_v, l)
|
||||||
|
k = m[0]
|
||||||
|
if k == None:
|
||||||
|
raise ValueError('invalid requirement line {}'.format(l))
|
||||||
|
if requirements.get(k) == None:
|
||||||
|
logg.info('adding {} -> {}'.format(k, l))
|
||||||
|
requirements[k] = l
|
||||||
|
else:
|
||||||
|
logg.debug('skipping {}'.format(l))
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
return list(requirements.values())
|
||||||
|
|
||||||
|
|
||||||
|
requirements = []
|
||||||
|
f = open('requirements.txt', 'r')
|
||||||
|
while True:
|
||||||
|
l = f.readline()
|
||||||
|
if l == '':
|
||||||
|
break
|
||||||
|
requirements.append(l.rstrip())
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
install_requires=requirements,
|
||||||
|
)
|
22
apps/cic-base/tests/base.py
Normal file
22
apps/cic-base/tests/base.py
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
# external imports
|
||||||
|
from chainlib.chain import ChainSpec
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from cic_base.rpc import setup as rpc_setup
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
|
class TestBase(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.chain_spec = ChainSpec('evm', 'foo', 42)
|
||||||
|
rpc_setup(self.chain_spec, 'http://localhost:8545', signer_provider='ipc://tmp/foo')
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
pass
|
14
apps/cic-base/tests/test_basic.py
Normal file
14
apps/cic-base/tests/test_basic.py
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# standard imports
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from tests.base import TestBase
|
||||||
|
|
||||||
|
|
||||||
|
class TestBasic(TestBase):
|
||||||
|
|
||||||
|
def test_basic(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
@ -9,5 +9,6 @@ semver==2.13.0
|
|||||||
psycopg2==2.8.6
|
psycopg2==2.8.6
|
||||||
celery==4.4.7
|
celery==4.4.7
|
||||||
redis==3.5.3
|
redis==3.5.3
|
||||||
|
rlp==2.0.1
|
||||||
chainsyncer[sql]~=0.0.3a3
|
chainsyncer[sql]~=0.0.3a3
|
||||||
erc20-faucet~=0.2.2a1
|
erc20-faucet~=0.2.2a1
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
cic-base==0.1.3a3+build.984b5cff
|
|
||||||
celery==4.4.7
|
|
||||||
crypto-dev-signer~=0.4.14b6
|
|
||||||
confini~=0.3.6rc3
|
|
||||||
cic-eth-registry~=0.5.6a1
|
|
||||||
redis==3.5.3
|
|
||||||
alembic==1.4.2
|
alembic==1.4.2
|
||||||
websockets==8.1
|
celery==4.4.7
|
||||||
requests~=2.24.0
|
|
||||||
eth_accounts_index~=0.0.12a1
|
|
||||||
erc20-transfer-authorization~=0.3.2a1
|
|
||||||
uWSGI==2.0.19.1
|
|
||||||
semver==2.13.0
|
|
||||||
websocket-client==0.57.0
|
|
||||||
moolb~=0.1.1b2
|
|
||||||
eth-address-index~=0.1.2a1
|
|
||||||
chainlib-eth~=0.0.5a1
|
chainlib-eth~=0.0.5a1
|
||||||
hexathon~=0.0.1a7
|
|
||||||
chainsyncer[sql]~=0.0.3a3
|
|
||||||
chainqueue~=0.0.2b5
|
chainqueue~=0.0.2b5
|
||||||
sarafu-faucet~=0.0.4a1
|
chainsyncer[sql]~=0.0.3a3
|
||||||
erc20-faucet~=0.2.2a1
|
cic-base==0.1.3a3+build.984b5cff
|
||||||
|
cic-eth-registry~=0.5.6a1
|
||||||
coincurve==15.0.0
|
coincurve==15.0.0
|
||||||
|
confini~=0.3.6rc3
|
||||||
|
crypto-dev-signer~=0.4.14b6
|
||||||
|
erc20-faucet~=0.2.2a1
|
||||||
|
erc20-transfer-authorization~=0.3.2a1
|
||||||
|
eth-address-index~=0.1.2a1
|
||||||
|
eth_accounts_index~=0.0.12a1
|
||||||
|
hexathon~=0.0.1a7
|
||||||
|
moolb~=0.1.1b2
|
||||||
potaahto~=0.0.1a2
|
potaahto~=0.0.1a2
|
||||||
pycryptodome==3.10.1
|
pycryptodome==3.10.1
|
||||||
|
redis==3.5.3
|
||||||
|
requests~=2.24.0
|
||||||
|
sarafu-faucet~=0.0.4a1
|
||||||
|
semver==2.13.0
|
||||||
|
uWSGI==2.0.19.1
|
||||||
|
websocket-client==0.57.0
|
||||||
|
websockets==8.1
|
||||||
|
@ -1 +1,6 @@
|
|||||||
cic_base[full_graph]==0.1.3a3+build.984b5cff
|
cic_base==0.1.3a3+build.984b5cff
|
||||||
|
africastalking==1.2.3
|
||||||
|
celery==4.4.7
|
||||||
|
confini==0.3.6rc3
|
||||||
|
semver==2.13.0
|
||||||
|
SQLAlchemy==1.3.20
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
cic-base[full_graph]==0.1.2b15
|
cic-base==0.1.2b15
|
||||||
sarafu-faucet==0.0.3a3
|
sarafu-faucet==0.0.3a3
|
||||||
sarafu-token==0.0.1a8
|
sarafu-token==0.0.1a8
|
||||||
cic-eth==0.11.0b16
|
cic-eth==0.11.0b16
|
||||||
|
@ -46,4 +46,16 @@ variables:
|
|||||||
when: always
|
when: always
|
||||||
|
|
||||||
|
|
||||||
|
.publish_python:
|
||||||
|
image: registry.gitlab.com/grassrootseconomics/cic-base-images:python-3.8.6-dev
|
||||||
|
stage: publish
|
||||||
|
variables:
|
||||||
|
#CI_DEBUG_TRACE: "true"
|
||||||
|
CIC_PACKAGE_REGISTRY_PROJECT_ID: 27624814
|
||||||
|
script:
|
||||||
|
- python -m pip wheel --extra-index-url https://pip.grassrootseconomics.net:8433 --wheel-dir=/tmp/wheelhouse -r requirements.txt
|
||||||
|
- python -m pip install --no-index --find-links=/tmp/wheelhouse -r requirements.txt
|
||||||
|
- python setup.py sdist bdist_wheel
|
||||||
|
- TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CIC_PACKAGE_REGISTRY_PROJECT_ID}/packages/pypi dist/*
|
||||||
|
# Below are the built dependencies
|
||||||
|
- TWINE_PASSWORD=${CI_JOB_TOKEN} TWINE_USERNAME=gitlab-ci-token python -m twine upload --repository-url ${CI_API_V4_URL}/projects/${CIC_PACKAGE_REGISTRY_PROJECT_ID}/packages/pypi /tmp/wheelhouse/*
|
||||||
|
Loading…
Reference in New Issue
Block a user