Package: eve-simple-esi
Eve Simple ESIThe Python 3+ library for simple andfastwork withhttps://esi.evetech.netdata.Thanks Qandra-Si ( https://github.com/Qandra-Si ) for help and basis of implementationThis library can:locally autorize with eve-online user (with gui and without gui interfase)automatically refresh autorization without guiget data (include data require autorization)post data (include data require autorization)install:pypi:pip install eve-simple-esimanual:Just put eve_simple_esi.py to directory with your projecthow to use:initialization:importeve_simple_esiasesisettings={'client_id':"<Client ID>",# go to https://developers.eveonline.com/ create app and get Client ID'client_secret':"<Secret Key>",# go to https://developers.eveonline.com/ create app and get Secret Key'client_callback_url':"<Callback URL>",# default http://localhost:8635/ need to be same as in your app in https://developers.eveonline.com/'user_agent':"<User Agent string>",'scopes':<listofscopes>,# ['publicData','esi-location.read_location.v1',...etc.]'port':<portforlocalwebserverforauthorization>,# default 8635}ESI=esi.ESI(settings)get data:data=ESI.op('/characters/{character_id}/',params={'character_id':2117005244})get multipaged data:data=ESI.op('/characters/{character_id}/assets/')# if cache is enabled you get all data from all pages with Etag and Last-Modified control# 'ESI.max_consistent_try' option can control maximum tries to get valid and consistent data (default 20)get forced single page data:data=ESI.op('/characters/{character_id}/assets/',params={'page':6},single=True)post data:data=ESI.op('/ui/autopilot/waypoint/',params={'add_to_beginning':False,'clear_other_waypoints':False,'destination_id':30000142},method="POST")post data with body:data=ESI.op('/universe/ids/',body=json.dumps(["Gila","Thrasher","Jita","CCP Alpha"]),method="POST")put data with body:data=ESI.op('/fleets/{fleet_id}/',params={'fleet_id':123456789},body=json.dumps({"is_free_move":True,"motd":"Fleet now is Free Move"}),method="PUT")delete data:data=ESI.op('/fleets/{fleet_id}/members/{member_id}/',params={'fleet_id':123456789,'member_id':987654321},method="DELETE")get data with headers and other fields:data=ESI.op('/characters/{character_id}/',raw=True)gui autorization:ESI.gui_auth()The builtin webserver starts only when needed for authorization and automatically shutdown when no authorization jobs foundcli autorization:ESI.auth()#need to go by url and after autorization insert code from url (http://localhost:8635/?code=<requested_code>&state=...)change character for request (if they storred):ESI.get("EVE Character Name")# if character never autorized in your program - ESI.gui_auth() or ESI.auth() calls automatically for logincomplicated requests:documentation#action_obj:
 {
 	'get':str, 			# (Required) Api address of Action

 	'link':str, 			# Create parameter with this link name and parent field data params.update({link:parent_field_data})

 	'flags':list, 			# ESI flags for current action get request [flag,...] (individual for each action get request data). see supported flags

 	'map':dict, 			# dict of anctions for fields {field_name:action_obj,...}

 	'fields':list or str, 		# list of raw fields in result [field_name,...] (if it str return only this field raw data and ignore map and id functions)

 	'name': str,			# rename parent field to this name

 	'params': dict, 		# dict of additional params for request {'param_name':value,...}

 	'list_filters':list of list 	# [[field_name,operator,value,filter_action], ...] 
 					# operator can be '==', '!=', '<', '>', '<=', '>=', 'in', 'not in', 'startswith', 'endswith', 're' 
 					# (with 're' operator your value must be compiled regexp object)
 					# action can be 'skip', 'stop'. see supported filter_action
 }

 #supported flags:
 'force_cache' 	# get data from cache and dont check etag
 'debug' 	# turns on debug

 #supported filter_action:
 'skip'		# skip current row
 'stop'		# skip current row, immediatley return collected data and stopexamplesget character data:complicated_map={'get':'/characters/{character_id}/','map':{'alliance_id':{'get':'/alliances/{alliance_id}/','fields':['name','ticker'],'name':'alliance','map':{'creator_id':{'link':'character_id','get':'/characters/{character_id}/','fields':['name'],'name':'creator'}}},'corporation_id':{'get':'/corporations/{corporation_id}/','map':{'ceo_id':{'link':'character_id','get':'/characters/{character_id}/','fields':['name','security_status'],'name':'ceo'}},'name':'corporation','fields':['name','ticker']}},'fields':['name','security_status','faction_id'],'id':'character_id'}data=ESI.map(complicated_map)returns:{"name":"Samanta ZORG","security_status":4.550539685,"character_id":"2112184541","alliance":{"name":"DEOS Alliance","ticker":"DEOS","alliance_id":99005266,"creator":{"name":"De-Caelo","character_id":94177853}},"corporation":{"name":"DC Reunion","ticker":"DCXLL","corporation_id":98313424,"ceo":{"name":"De-Caelo","security_status":1.496001863,"character_id":94177853}}}get corporate industry jobs:complicated_map={'get':'/characters/{character_id}/','flags':['force_cache'],'map':{'corporation_id':{'get':'/corporations/{corporation_id}/industry/jobs/','map':{'product_type_id':{'link':'type_id','get':'/universe/types/{type_id}/','flags':['force_cache'],'fields':'name','name':'job'},'installer_id':{'link':'character_id','get':'/characters/{character_id}/','flags':['force_cache'],'fields':'name','name':'installer'},'facility_id':{'link':'structure_id','get':'/universe/structures/{structure_id}/','flags':['force_cache'],'fields':'name','name':'facility'}},'fields':['job_id','start_date','end_date','status','runs','activity_id'],'params':{'include_completed':True},'name':'industry_jobs','list_filters':[['status','==','delivered','skip'],['start_date','<',"2020-06-26T22:13:56Z",'stop'],]}}}data=ESI.map(complicated_map)returns:[{"job_id":432601643,"start_date":"2020-07-31T06:17:03Z","end_date":"2020-07-31T21:00:30Z","status":"cancelled","runs":1,"activity_id":5,"corporation_id":98313424,"job":"Strip Miner I Blueprint","installer":"Simba Researcher","facility":"A4B-V5 - Lab House"},{"job_id":430265203,"start_date":"2020-07-08T13:14:32Z","end_date":"2020-09-11T06:52:12Z","status":"active","runs":1,"activity_id":4,"corporation_id":98313424,"job":"Capital Hull Repairer I Blueprint","installer":"Irida ZORG","facility":"A4B-V5 - Lab House"},{"job_id":429341629,"start_date":"2020-06-29T15:31:43Z","end_date":"2020-06-30T06:21:29Z","status":"cancelled","runs":1,"activity_id":5,"corporation_id":98313424,"job":"Radio L Blueprint","installer":"Himera dior","facility":"A4B-V5 - Lab House"},...]get character in initialize:ESI=esi.ESI(settings,name="EVE Character Name")force cli autorization if no storred character:ESI=esi.ESI(settings,name="EVE Character Name",gui=False)use multiplue instance:importeve_simple_esiasesiweb_server=esi.ESIAuthWebServer(local_address='localhost',port=8635)# make one instance of webserver for all ESI instancesESI1=esi.ESI(settings,name="first EVE Character Name",callback_web_server=web_server)ESI2=esi.ESI(settings,callback_web_server=web_server)ESI3=esi.ESI(settings,callback_web_server=web_server)ESI3.gui_auth()fash user switch:importeve_simple_esiasesiESI=esi.ESI(settings,name="first EVE Character Name")data=ESI.op('/characters/{character_id}/')ESI.get("second EVE Character Name")data=ESI.op('/characters/{character_id}/')data=ESI.op('/ui/autopilot/waypoint/',params={'add_to_beginning':False,'clear_other_waypoints':False,'destination_id':30000142},method="POST")ESI.get("third EVE Character Name")data=ESI.op('/characters/{character_id}/')autoapply self character information if autorized:ESI=esi.ESI(settings,name="EVE Character Name")data=ESI.op('/characters/{character_id}/')# data for character_id with "EVE Character Name" namedata=ESI.op('/characters/{character_id}/',params={'character_id':2117005244})# data for character_id: 2117005244you also can use your own function to get all messages from ESI class:defmy_print_function(text_string):...print(text_string)# as example...ESI=esi.ESI(settings,callback_print=my_print_function)and your own function for request auth_code:defmy_input_function(text_string):...returninput(text_string)# as exampleESI=esi.ESI(settings,callback_input=my_input_function)and your own class for store user data:classcustom_callback_saved_data:defread(char_name):...returnjson.loads(saved_data)defwrite(char_name,data):saved_data=json.dumps(data)...ESI=esi.ESI(settings,callback_saved_data=custom_callback_saved_data)and your own webserver class:classcustom_callback_web_server:def__init__(self,address,port):...defreg_callback(state_string,on_success_function,on_error_function):......ESI=esi.ESI(settings,callback_web_server=custom_callback_web_server)and your own cache server class:classcustom_callback_cache_server:defGet(self,key):#...ifkeyincache:returndataelse:returnNonedefDel(self,key):#...defSet(self,key,data):#...defClear(self):#...defClose(self):#...defSync(self):#...ESI=esi.ESI(settings,callback_cache_server=custom_callback_cache_server)