Package: python-feclient
Python client for Fusion ExplorerIntroductionThis utility makes easier to use Fusion Explorer API which uses JSON-RPC protocol.InstallationRequires python version 3.7 or later.To install the latest release onPyPI,
simply run:pip3installpython-feclientOr to install the latest version, run:gitclonehttps://github.com/FusionSolutions/python-feclient.gitcdpython-feclient
python3setup.pyinstallCommand Line InterfaceIMPORTANTThe CLI utility downloads method and bitmask definitions from the server and stores it temporary for the terminal session. You can disable it when you set the following environment key:FECLI_DISABLE_CACHE=1For get usage information please use:$fexplorer-cliPython libraryUsageJust import theClientclass from thefeClientlibrary and it is ready to use.Example for standard usage:fromfeClientimportClientwithClient()asfec:request=fec.request("ping")print(request.get())IMPORTANTThe initialized client isNOTsafe for threads or multi-process at the same time, unless when youClient.cloneit before you give it to the thread/process.Initialize ClientfeClient.Client(projectPublicKey:Optional[Union[str,bytes]]=None,projectSecretKey:Optional[Union[str,bytes]]=None,timeWindow:int=60,convertNumbers:Optional[str]=None,retryCount:int=10,retryDelay:Union[int,float]=5,connectTimeout:int=15,transferTimeout:int=320,disableCompression:bool=False,log:Optional[Logger]=None,signal:Optional[T_Signal]=None,target:Tuple[str,int]=("api.fusionexplorer.io",443),httpHost:Optional[str]=None,ssl:bool=True)ParameterTypeDefaultDescriptionprojectPublicKeyOptional[Union[str, bytes]]NoneProject public key - if available - 16 byte hex like: "0x9cd433f765a8818c1002241190deae51".projectSecretKeyOptional[Union[str, bytes]]NoneProject secret key - if available - 16 byte hex like: "0xace3ebb9a17b5b40b8b2bd87b92296b1".Required whenprojectPublicKeyis used.timeWindowint60Security time window for avoid old queries repeat attack. The amount is in seconds.convertNumbersOptional[str]NonePlease seenumbers.retryCountint10How many retries should be have before Error raises during operation.retryDelayUnion[int, float]5Delay in seconds between two retry. It can also be a fractal number like0.25.connectTimeoutUnion[int, float]15Socket connection timeout in second. It can also be a fractal number like4.5.transferTimeoutUnion[int, float]320Socket transfer/Receive timeout in second. It can also be a fractal number like4.5.disableCompressionboolFalseProhibit asking server for compressed response.logOptional[Logger]NoneInitializedLoggerclass frompython-fsloggerpackage.signalOptional[T_Signal]NoneSignal, SoftSignal or HardSignal class frompython-fslsignalpackage.targetTuple[str, int]("api.fusionexplorer.io", 443)Explorer server address and port. May you  do not need set this.httpHostOptional[str]NoneHTTPhostheader during request. When is not set, then target data will be used. May you  do not need set this.sslboolTrueInitialize SSL for the socket. May you do not need set this.NumbersIf you need the integers in other format like hexadecimal, you can setconvertNumbersduring initialize. This option will be sent with every request, and the server will format the response before it sends back to the client.Supported values:Noneor"default": Protocol based predefined conversion. This client uses JSONRPC-P protocol which equals"none"for this value."none": Integers and floats will be not converted and stays in original type."str": Integers and floats will be converted into string. For example:balance:int = 55will bebalance:str = "55"``, andpercent:float = 3.14will bepercent:str = "3.14"`"hex": Integers and floats will be converted into string, but integers will be in hexadecimal format with0xprefix. For example:balance:int = 55will bebalance:str = "0x37"``, andpercent:float = 3.14will bepercent:str = "3.14"`ClientAPI referenceCreate requestClient.request(method:str,args:List[Any]=[],kwargs:Dict[str,Any]={},id:Optional[Union[str,int]]=None,path:str="/")->RequestParameterTypeDefaultDescriptionmethodstrMethod name.argsList[Any][]Arguments of parameters.kwargsDict[str, Any]{}Keyword arguments of parameters.idOptional[Union[str, int]]NoneRequest identifier, forNonea sequenced number will be used.Do notduplicate ID's in the same instance.pathstr/HTTP request path. May you  do not need set this.Returns aRequestobject.Create iteratorfeClient.Client.createIterator(method:str,*args:Any,sortBy:Optional[str]=None,fromKey:Optional[str]=None,desc:Optional[bool]=None,bitmask:Optional[int]=None,chunks:int=12)ParameterTypeDefaultDescriptionmethodstrMethod name which need to begin withiter.*argsList[Any]This parameter definition is given by the method.sortByOptional[str]NoneSorting definition key.fromKeyOptional[str]NoneLast referenced item ID from where you want to continue the iteration.descOptional[bool]NoneWhenTruewill be descending, whenFalsewill be ascending ordered.bitmaskOptional[int]NoneBitmask value.chunksint12Amount of the rows what the iterator should precache.Returns afeClient.FEIteratorobject with inside aclonedclient.
You can read morehere.Example usage:fromfeClientimportClientwithClient()asfec:forkey,datainfec.createIterator("iterTransactionInputs","btc","0x8c659902068f0af33849a6d49c4c92150bbb28a9d60c766e47379bbb04726ea0",chunks=5):print((key,data))Example for continue iteration from the last element:fromfeClientimportClientfromitertoolsimportislicewithClient()asfec:forkey,datainislice(fec.createIterator("iterAddresses","btc",sortBy="balance",desc=True,chunks=2),2):print(data)forkey,datainfec.createIterator("iterAddresses","btc",sortBy="balance",fromKey=key,desc=True,chunks=2):print(data)breakThewithstatementTheClienthas enter/exit functions, so you can use with thewithstatement.Attentiondo not use the same instance when you are done with the statement, because on exit the socket will be closed and all states will be reset.Example:fromfeClientimportClientfec=Client()withfecasc:request=fec.request("ping")print(request.get())Close connectionfeClient.Client.close()Closing connection and reset all states.Clear cachesfeClient.Client.clear()Clearing request and response cache. It is automatic during de-allocation.ClonefeClient.Client.clone(**kwargs)Creates a newClientinstance with the initialized parameters. When you use threading or multi-processing you should give an object like this forward. You can give keyword arguments to replace someinitialization parameter.Example:importthreadingfromfeClientimportClientfec=Client()defthreadFn(id,c):foriinrange(2):request=c.request("ping")print("Thread-{}:{}".format(id,request.get()))threads=[]foriinrange(4):threads.append(threading.Thread(target=threadFn,args=(i,fec.clone(convertNumbers="hex"))))forthinthreads:th.start()request=fec.request("ping")print("Main :{}".format(request.get()))forthinthreads:th.join()ObjectsRequest objectYou can create this object withfeClient.Client.requestfunction.Functions:Request.get(): Returns the request response. On any server error theClientwill reconnect and send all non-responded requests again.Request.getDelay(): Returns the response delay in seconds as float.Request.getID(): Returns the request ID.Request.isDone(): ReturnsTruewhen response arrived andFalsewhen not.Request.getUID(): Returns the unique response ID asstr. On an issue report you can give this as reference.Request.isSuccess(): ReturnsTruewhen no error happened elseFalsewhen something went wrong.FEIterator objectYou can create this object withfeClient.Client.createIteratorfunction.This is a simple iterator extended with the following functions:it.__next__()andit.next(): Returns a tuple:( key, data ). Technically pops the cache first item and returns it back. The key is the unique ID of the item, may you need reference this when you want continue the iteration later.it.checkNext(): This function returns the same as the__next__, but will not delete from the cache. Calling this function the iteration would not be moving forward. If there is nothing for nextStopIterationwill be raised.it.hasNext(): Will returnTruewhen next data exists,Falsewhen not.ExceptionsBase errorfeClient.BaseRPCError(Exception)This is anExceptioninstance with amessageattribute.
Example to catch errors:try:# some request..exceptfeClient.BaseRPCErroraserr:print(err.message)# or do something else..Initialization errorfeClient.InitializationError(BaseRPCError)Will be raises when you give bad parameters during initializing the client.Socket errorfeClient.SocketError(BaseRPCError)Will be raised when the client has lost the connection with the server or can not connect to it.Message errorfeClient.MessageError(BaseRPCError)Will be raised when the server gives an non-parseable response.Request errorfeClient.RequestError(BaseRPCError)Will be raised when you give bad type forfeClient.Client.requestidparameter or theidis already in use.Response errorfeClient.ResponseError(BaseRPCError)Will be raised:when the server did not answered for the request or you did not have sent the request for that ID.When error happens during iteration ofFEIteratorobject.ContributionBug reports, constructive criticism and suggestions are welcome. If you have some create an issue ongithub.API LimitationsServer limitations are very strict.
One way semaphores are used:Only one for the guests (GUEST session). For more details see above.One for each projects (PROJECT session).One for each user (USER session).You will be sorted in GUEST session when:You don not not provide any auth.You provide invalid auth.Your subscription is expired.Your subscription has exceeded the daily quota.For private subscribe request please send anemail.CopyrightAll of the code in this distribution is Copyright (c) 2021 Fusion Solutions Kft.The utility is made available under the GNU General Public license. The included LICENSE file describes this in detail.WarrantyTHIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE USE OF THIS SOFTWARE IS WITH YOU.IN NO EVENT WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY, BE LIABLE TO YOU FOR ANY DAMAGES, EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.Again, see the included LICENSE file for specific legal details.