Skip to content
Snippets Groups Projects
Commit 51990ebb authored by Caner Candan's avatar Caner Candan
Browse files

+ added initial API files

parent 63962d75
No related branches found
No related tags found
No related merge requests found
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
__all__ = ['api']
__author__ = 'Caner Candan'
__version__ = '0.0.1'
__nonsense__ = 'uCoin'
import requests
URL = 'http://mycurrency.candan.fr:8081'
AUTH = False
class API:
"""APIRequest is a class used as an interface. The intermediate derivated classes are the modules and the leaf classes are the API requests."""
def __init__(self, module, url=URL, auth=AUTH):
"""
Asks a module in order to create the url used then by derivated classes.
Arguments:
- `module`: module name
- `url`: url defining the host and port of the server
- `auth`: enables to get multipart/signed messages.
"""
self.url = '%s/%s' % (url, module)
self.headers = {}
if auth: self.headers['Accept'] = 'multipart/signed'
def reverse_url(self, path):
"""
Reverses the url using self.url and path given in parameter.
Arguments:
- `path`: the request path
"""
return self.url + path
def get(self):
"""interface purpose for GET request"""
pass
def post(self):
"""interface purpose for POST request"""
pass
def requests_get(self, path):
"""
Requests GET wrapper in order to use API parameters.
Arguments:
- `path`: the request path
"""
return requests.get(self.reverse_url(path), headers=self.headers)
def requests_post(self, path):
"""
Requests POST wrapper in order to use API parameters.
Arguments:
- `path`: the request path
"""
return requests.post(self.reverse_url(path), headers=self.headers)
def merkle_easy_parser(self, path):
root = self.requests_get(path + '?leaves=true').json()
for leaf in root['leaves']:
yield self.requests_get(path + '?leaf=%s' % leaf).json()['leaf']
from . import pks, ucg, hdc
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from .. import API
class HDC(API):
def __init__(self, module='hdc'):
super().__init__(module)
from . import amendments, transactions
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from . import HDC
class Base(HDC):
def __init__(self):
super().__init__('hdc/amendments')
class List(Base):
"""GET the list of amendments through the previousHash value."""
def get(self):
"""creates a generator with one amendment per iteration."""
current = self.requests_get('/current').json()
yield current
while 'previousHash' in current and current['previousHash']:
current['previousNumber'] = current['number']-1
current = self.requests_get('/view/%(previousNumber)d-%(previousHash)s/self' % current).json()
yield current
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from . import HDC
class Base(HDC):
def __init__(self):
super().__init__('hdc/transactions')
class All(Base):
"""GET all the transactions stored by this node."""
def get(self):
"""creates a generator with one transaction per iteration."""
return self.merkle_easy_parser('/all')
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from .. import API
class PKS(API):
def __init__(self, module='pks'):
super().__init__(module)
class All(PKS):
"""GET all the received public keys."""
def get(self):
"""creates a generator with one public key per iteration."""
return self.merkle_easy_parser('/all')
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from .. import API
class UCG(API):
def __init__(self, module='ucg'):
super().__init__(module)
class Pubkey(UCG):
"""GET the public key of the peer."""
def get(self):
return self.requests_get('/pubkey').text
class Peering(UCG):
"""GET peering information about a peer."""
def get(self):
return self.requests_get('/peering').json()
from . import peering
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from .. import UCG
class Base(UCG):
def __init__(self):
super().__init__('ucg/peering')
class Keys(Base):
"""GET PGP keys' fingerprint this node manages, i.e. this node will have transactions history and follow ohter nodes for this history."""
def get(self):
"""creates a generator with one transaction per iteration."""
return self.merkle_easy_parser('/keys')
class Peer(Base):
"""GET the peering informations of this node."""
def get(self):
"""returns peering entry of the node."""
return self.requests_get('/peer').json()
class Peers(Base):
"""GET peering entries of every node inside the currency network."""
def get(self):
"""creates a generator with one peering entry per iteration."""
return self.merkle_easy_parser('/peers')
def post(self):
pass
from . import peers
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from . import UCG
class Base(UCG):
def __init__(self):
super().__init__('ucg/peering/peers')
class Stream(Base):
"""GET a list of peers this node is listening to/by for ANY incoming transaction."""
def __init__(self, request, pgp_fingerprint=None):
"""
Use the pgp fingerprint parameter in order to fit the result.
Arguments:
- `request`: select the stream request
- `pgp_fingerprint`: pgp fingerprint to use as a filter
"""
super().__init__()
self.request = request
self.pgp_fingerprint = pgp_fingerprint
def get(self):
"""returns the corresponding peer list."""
if not self.pgp_fingerprint:
return self.requests_get('/%s' % self.request).json()
return self.requests_get('/%s/%s' % (self.request, self.pgp_fingerprint)).json()
class UpStream(Stream):
"""GET a list of peers this node is listening to for ANY incoming transaction."""
def __init__(self, pgp_fingerprint=None):
"""
Use the pgp fingerprint parameter in order to fit the result.
Arguments:
- `pgp_fingerprint`: pgp fingerprint to use as a filter
"""
super().__init__('upstream', pgp_fingerprint)
class DownStream(Stream):
"""GET a list of peers this node is listening by for ANY incoming transaction."""
def __init__(self, pgp_fingerprint=None):
"""
Use the pgp fingerprint parameter in order to fit the result.
Arguments:
- `pgp_fingerprint`: pgp fingerprint to use as a filter
"""
super().__init__('downstream', pgp_fingerprint)
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2
# as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
import argparse, logging, sys
from collections import OrderedDict
class Parser(argparse.ArgumentParser):
"""Wrapper class added logging support"""
def __init__(self, description='', verbose='quiet', formatter_class=argparse.ArgumentDefaultsHelpFormatter):
"""
We add all the common options to manage verbosity.
"""
argparse.ArgumentParser.__init__(self, description=description, formatter_class=formatter_class)
self.levels = OrderedDict([('debug', logging.DEBUG),
('info', logging.INFO),
('warning', logging.WARNING),
('error', logging.ERROR),
('quiet', logging.CRITICAL),
])
self.add_argument('--verbose', '-v', choices=[x for x in self.levels.keys()], default=verbose, help='set a verbosity level')
self.add_argument('--levels', '-l', action='store_true', default=False, help='list all the verbosity levels')
self.add_argument('--output', '-o', help='all the logging messages are redirected to the specified filename.')
self.add_argument('--debug', '-d', action='store_const', const='debug', dest='verbose', help='Diplay all the messages.')
self.add_argument('--info', '-i', action='store_const', const='info', dest='verbose', help='Diplay the info messages.')
self.add_argument('--warning', '-w', action='store_const', const='warning', dest='verbose', help='Only diplay the warning and error messages.')
self.add_argument('--error', '-e', action='store_const', const='error', dest='verbose', help='Only diplay the error messages')
self.add_argument('--quiet', '-q', action='store_const', const='quiet', dest='verbose', help='Quiet level of verbosity only displaying the critical error messages.')
def __call__(self):
args = self.parse_args()
if args.levels:
print("Here's the verbose levels available:")
for keys in self.levels.keys():
print("\t", keys)
sys.exit()
if (args.output):
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
filename=args.output, filemode='a'
)
else:
logging.basicConfig(
level=self.levels.get(args.verbose, logging.NOTSET),
format='%(name)-12s: %(levelname)-8s %(message)s'
)
return args
ucoin.py 0 → 100755
#!/usr/bin/env python3
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Authors:
# Caner Candan <caner@candan.fr>, http://caner.candan.fr
#
from parser import Parser
from pprint import pprint
import api
URL = 'http://mycurrency.candan.fr:8081'
AUTH = False
def action_peering():
pprint(api.ucg.Peering().get())
def action_amendments():
for am in api.hdc.amendments.List().get():
print(am['number'])
def action_transactions():
for tx in api.hdc.transactions.All().get():
print(tx['hash'])
if __name__ == '__main__':
parser = Parser(description='ucoin client.', verbose='error')
parser.add_argument('--peering', '-p', help='get peering',
action='store_const', dest='action', const=action_peering)
parser.add_argument('--amendments', '-a', help='get amendments list',
action='store_const', dest='action', const=action_amendments)
parser.add_argument('--transactions', '-t', help='get transactions list',
action='store_const', dest='action', const=action_transactions)
args = parser()
if args.action: args.action()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment