Exemple #1
0
def towers_tower_id_processes_process_id_delete(tower_id, process_id, api_key):
    """
    towers_tower_id_processes_process_id_delete
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: None
    """
    qProcess = application_map.Process
    qTower = application_map.Tower
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    try:
        q_process = q_tower.processes.filter(qProcess.id == process_id).one()
        session.delete(q_process)
        session.commit()
        return None, 200

    except NoResultFound:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404
def operation_keys_post(api_key, new_key):
    """
    operation_keys_post
    Creates a new operation access sub-key with the access scopes provided, and then returns the key in the response. 
    :param api_key: Operation Master Access Key
    :type api_key: str
    :param new_key: name/permission info for the new key
    :type new_key: NewKey

    :rtype: Key
    """
    if connexion.request.is_json:
        key = Key.from_dict(connexion.request.get_json())

    session = application_map.Session()
    qKey = application_map.Key

    key.value = uuid.uuid4().hex

    if not is_valid_permission(key.permission):
        error = Error('Bad Request: Permission {} is not valid.'.format(
            key.permission))
        return error, 400
    elif key.permission == 'master':
        error = Error('Cannot create master key.')
        return error, 400
    else:
        q_newkey = qKey(name=key.name,
                        value=key.value,
                        permission=key.permission,
                        operation_id=api_key.operation_id)
        session.add(q_newkey)
        session.commit()

        return key, 200
def operation_keys_sub_key_delete(sub_key, api_key):
    """
    operation_keys_sub_key_delete
    Delete an access sub-key.  The specified key will no longer be valid for accessing any portion of the given operation. 
    :param sub_key: Operation Access Sub-key
    :type sub_key: str
    :param api_key: Operation Master Access Key
    :type api_key: str

    :rtype: None
    """
    qKey = application_map.Key
    session = application_map.Session()
    q_key = session.query(qKey).filter(qKey.value == sub_key).filter(
        qKey.operation_id == api_key.operation_id).one_or_none()

    if q_key is None:
        error = Error('Key `{}` not Found'.format(sub_key))
        return error, 404
    elif q_key.permission == 'master':
        error = Error('Cannot delete master key.')
        return error, 400
    else:
        session.delete(q_key)
        session.commit()
        return None, 200
Exemple #4
0
def towers_tower_id_processes_process_id_equipment_equipment_id_get(
        tower_id, process_id, equipment_id, api_key):
    """
    towers_tower_id_processes_process_id_equipment_equipment_id_get
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param equipment_id: Id of equipment that needs fetched.
    :type equipment_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: Equipment
    """
    qEquipment = application_map.Equipment
    qEquipmentInfo = info_map.Equipment
    qTower = application_map.Tower
    qProcess = application_map.Process
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    # find process
    q_process = q_tower.processes.filter(
        qProcess.id == process_id).one_or_none()
    if q_process is None or q_process.id != process_id:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404

    q_equipment = q_process.equipment.filter(
        qEquipment.id == equipment_id).one_or_none()
    if q_equipment is None or q_equipment.id != equipment_id:
        error = Error('Equipment `{}` not Found'.format(equipment_id))
        return error, 404

    equipment = Equipment(id=q_equipment.id,
                          type=q_equipment.type,
                          name=q_equipment.name,
                          resource=q_equipment.resource,
                          contains=q_equipment.contains,
                          last_updated=q_equipment.last_updated,
                          online=q_equipment.online,
                          inputs=[
                              Link(source=l.source, material=l.resource)
                              for l in q_equipment.inputs
                          ],
                          outputs=[
                              Link(target=l.target, material=l.resource)
                              for l in q_equipment.outputs
                          ])

    return equipment, 200
Exemple #5
0
def towers_tower_id_processes_process_id_equipment_get(tower_id, process_id,
                                                       api_key):
    """
    towers_tower_id_processes_process_id_equipment_get
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: List[Equipment]
    """
    qEquipment = application_map.Equipment
    qEquipmentInfo = info_map.Equipment
    qTower = application_map.Tower
    qProcess = application_map.Process
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404
    # find process
    q_process = q_tower.processes.filter(
        qProcess.id == process_id).one_or_none()
    if q_process is None or q_process.id != process_id:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404

    equipment = []
    for e in q_process.equipment:
        equipment.append(
            Equipment(id=e.id,
                      type=e.type,
                      name=e.name,
                      resource=e.resource,
                      contains=e.contains,
                      last_updated=e.last_updated,
                      online=e.online,
                      inputs=[
                          Link(source=l.source, material=l.resource)
                          for l in e.inputs
                      ],
                      outputs=[
                          Link(target=l.target, material=l.resource)
                          for l in e.outputs
                      ]))  # need to implement links still

    return equipment, 200
Exemple #6
0
def towers_tower_id_processes_process_id_link_post(tower_id, process_id, link,
                                                   api_key):
    """
    towers_tower_id_processes_process_id_link_post
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param link: 
    :type link: dict | bytes
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: None
    """
    if connexion.request.is_json:
        link = Link.from_dict(connexion.request.get_json())

    qEquipment = application_map.Equipment
    qEquipmentInfo = info_map.Equipment
    qTower = application_map.Tower
    qProcess = application_map.Process
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    q_process = q_tower.processes.filter(
        qProcess.id == process_id).one_or_none()
    if q_process is None or q_process.id != process_id:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404

    # testing to see if the equipment are even valid
    try:
        q_source = session.query(qEquipment).filter(
            and_(qEquipment.id == link.source,
                 qEquipment.process_id == process_id)).one()
        q_target = session.query(qEquipment).filter(
            and_(qEquipment.id == link.target,
                 qEquipment.process_id == process_id)).one()
        make_link(link.source, link.target, link.material)

    except NoResultFound:
        error = Error('Equipment to link not found.')
        return error, 400
    except InvalidLinkMaterial as e:
        return Error(message=str(e)), 400
Exemple #7
0
def towers_tower_id_processes_get(tower_id, api_key):
    """
    towers_tower_id_processes_get
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: List[Process]
    """
    qProcess = application_map.Process
    qTower = application_map.Tower
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    processes = []
    for q_process in q_tower.processes:
        processes.append(
            Process(id=q_process.id,
                    equipment=[e.id for e in q_process.equipment],
                    final_outputs=[]))

    return processes, 200
Exemple #8
0
def towers_tower_id_processes_post(tower_id, api_key):
    """
    towers_tower_id_processes_post
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: Process
    """
    qProcess = application_map.Process
    qTower = application_map.Tower
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    q_process = qProcess()
    q_tower.processes.append(q_process)
    session.commit()
    q_process.id += random.randint(
        0, 99)  # add some uncertainty so that id is not directly count
    session.commit()  # commit the updated id
    process = Process(id=q_process.id, equipment=[], final_outputs=[])

    return process, 200
Exemple #9
0
def info_towers_type_id_get(type_id):
    """
    info_towers_type_id_get
    Gets type details for a specific tower with `type_id`. 
    :param type_id: Type of the item that needs fetched.
    :type type_id: int

    :rtype: TowerInfo
    """
    session = info_map.Session()

    q = session.query(info_map.Tower).filter(info_map.Tower.type == type_id)
    q_tower = q.one_or_none()

    if q_tower is None:
        error = Error('Type {} Not Found'.format(type_id))
        return error, 404
    else:
        tower = TowerInfo(type=q_tower.type,
                          fuel_bay=q_tower.fuel_bay,
                          stront_bay=q_tower.stront_bay,
                          name=q_tower.name,
                          storage_mult=q_tower.storage_mult,
                          cpu=q_tower.cpu,
                          powergrid=q_tower.powergrid,
                          fuel_usage=q_tower.fuel_usage,
                          stront_usage=q_tower.stront_usage,
                          fuel_type=q_tower.fuel_type)

        return tower, 200
Exemple #10
0
def info_equipment_type_id_get(type_id):
    """
    ...
    Gets information about a specific silo or reactor of type `type_id`.
    :param type_id: Type of the item that needs fetched.
    :type type_id: float

    :rtype: EquipmentInfo
    """
    session = info_map.Session()

    q = session.query(
        info_map.Equipment).filter(info_map.Equipment.type == type_id)
    q_equipment = q.one_or_none()

    if q_equipment is not None:
        equipment = EquipmentInfo(
            type=q_equipment.type,
            name=q_equipment.name,
            group=q_equipment.group_id,
            capacity=q_equipment.capacity,
            fitting=EquipmentInfoFitting(cpu=q_equipment.cpu,
                                         powergrid=q_equipment.powergrid),
            allowed_groups=[g.group_id for g in q_equipment.groups])

        return equipment

    else:
        error = Error('Type {} Not Found'.format(type_id))
        return error, 404
Exemple #11
0
def towers_tower_id_processes_process_id_equipment_equipment_id_delete(
        tower_id, process_id, equipment_id, api_key):
    """
    towers_tower_id_processes_process_id_equipment_equipment_id_delete
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param equipment_id: Id of equipment that needs fetched.
    :type equipment_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: None
    """
    qEquipment = application_map.Equipment
    qEquipmentInfo = info_map.Equipment
    qTower = application_map.Tower
    qProcess = application_map.Process
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    # find process
    q_process = q_tower.processes.filter(
        qProcess.id == process_id).one_or_none()
    if q_process is None or q_process.id != process_id:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404

    q_equipment = q_process.equipment.filter(
        qEquipment.id == equipment_id).one_or_none()
    if q_equipment is None or q_equipment.id != equipment_id:
        error = Error('Equipment `{}` not Found'.format(equipment_id))
        return error, 404

    session.delete(q_equipment)
    session.commit()

    return None, 200
Exemple #12
0
def towers_tower_id_processes_process_id_get(tower_id, process_id, api_key):
    """
    towers_tower_id_processes_process_id_get
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: Process
    """
    qProcess = application_map.Process
    qTower = application_map.Tower
    qEquipment = application_map.Equipment
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    try:
        q_process = q_tower.processes.filter(qProcess.id == process_id).one()
        equipment = [e.id for e in q_process.equipment]

        process_tree = ProcessTree.fromId(q_process.id)
        endpoints = process_tree.production_endpoints()

        final_outputs = [
            e.resource
            for e in q_process.equipment.filter(qEquipment.id.in_(endpoints))
        ]
        # final_outputs = [e.id for e in endpoints]
        process = Process(
            id=q_process.id, equipment=equipment,
            final_outputs=final_outputs)  # not fully implemnted yet

        return process, 200

    except NoResultFound:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404
def operation_keys_sub_key_patch(sub_key, api_key, key_update):
    """
    operation_keys_sub_key_patch
    Update key_update for the given access sub-key. 
    :param sub_key: Operation Access Sub-key
    :type sub_key: str
    :param api_key: Operation Master Access Key
    :type api_key: str
    :param key_update:
    :type key_update: NewKey

    :rtype: NewKey
    """
    if connexion.request.is_json:
        key_update = Key.from_dict(connexion.request.get_json())

    qKey = application_map.Key
    session = application_map.Session()

    if not is_valid_permission(key_update.permission):
        error = Error('Bad Request: Permission {} is not valid.'.format(
            key_update.permission))
        return error, 400
    elif key_update.permission == 'master':
        error = Error('Cannot set a sub key with permission `master`.')
        return error, 400

    q_key = session.query(qKey).filter(qKey.value == sub_key).filter(
        qKey.operation_id == api_key.operation_id).one_or_none()
    key_update.value = q_key.value
    if q_key is None:
        error = Error('Key `{}` not Found'.format(sub_key))
        return error, 404

    elif q_key.permission == 'master':
        error = Error('Cannot alter Master Key')
        return error, 400

    else:
        q_key.name = q_key.name if key_update.name is None else key_update.name
        q_key.permission = q_key.permission if key_update.permission is None else key_update.permission
        session.commit()
        return key_update, 200
Exemple #14
0
def info_reactions_type_id_get(type_id):
    """
    info_reactions_type_id_get
    Gets information about a specific reaction of type `type_id`. 
    :param type_id: Type of the item that needs fetched.
    :type type_id: float

    :rtype: Reaction
    """
    reactions = _reaction_by_type(type_id)
    if reactions is None:
        error = Error('Type {} Not Found'.format(type_id))
        return error, 404
    else:
        return reactions, 200
Exemple #15
0
def towers_tower_id_delete(tower_id, api_key):
    """
    towers_tower_id_delete
    Delete a specific tower and all its equipment/processes. 
    :param tower_id: Id number of the tower to be deleted.
    :type tower_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: None
    """
    qTower = application_map.Tower
    session = application_map.Session()

    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404
    else:
        session.delete(q_tower)
        session.commit()
    return None, 200
def operation_keys_sub_key_get(sub_key, api_key):
    """
    operation_keys_sub_key_get
    Gets the permission settings of the given access key. 
    :param sub_key: Operation Access Sub-key
    :type sub_key: str
    :param api_key: Operation Master Access Key
    :type api_key: str

    :rtype: Key
    """
    qKey = application_map.Key
    session = application_map.Session()
    q_key = session.query(qKey).filter(qKey.value == sub_key).filter(
        qKey.operation_id == api_key.operation_id).one_or_none()
    if q_key is None:
        error = Error('Key `{}` not Found'.format(sub_key))
        return error, 404
    else:
        key = Key(name=q_key.name,
                  value=q_key.value,
                  permission=q_key.permission)
        return key, 200
Exemple #17
0
def towers_tower_id_get(tower_id, api_key):
    """
    towers_tower_id_get
    Gets details for a specific tower with `type_id`. 
    :param tower_id: Type of the item that needs fetched.
    :type tower_id: int
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: TowerDetails
    """

    qTower = application_map.Tower
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404
    else:
        tower_details = TowerDetails(
            id=q_tower.id,
            type=q_tower.type,
            system=q_tower.system,
            planet=q_tower.planet,
            moon=q_tower.moon,
            name=q_tower.name,
            cycles_at=q_tower.cycles_at,
            stront_count=q_tower.stront_count,
            fuel_count=q_tower.fuel_count,
            fuel_last_update=q_tower.fuel_last_update,
            online=q_tower.online,
            sov=q_tower.sov,
            processes=[p.id for p in q_tower.processes])

        return tower_details, 200
Exemple #18
0
def info_materials_type_id_get(type_id):
    """
    info_materials_type_id_get
    Gets type details for a specific item with `type_id`. 
    :param type_id: Type of the item that needs fetched.
    :type type_id: int

    :rtype: MaterialInfo
    """
    session = info_map.Session()
    q = session.query(
        info_map.Material).filter(info_map.Material.type == type_id)

    mat = q.one_or_none()  # return the only result or `None`

    if mat is not None:
        material_info = MaterialInfo(type=mat.type,
                                     group=mat.group_id,
                                     name=mat.name,
                                     volume=mat.volume)
        return material_info, 200
    else:
        error = Error('Type {} Not Found'.format(type_id))
        return error, 404
Exemple #19
0
def towers_tower_id_processes_process_id_equipment_equipment_id_patch(
        tower_id, process_id, equipment_id, equipment, api_key):
    """
    towers_tower_id_processes_process_id_equipment_equipment_id_patch
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param equipment_id: Id of equipment that needs fetched.
    :type equipment_id: int
    :param equipment: 
    :type equipment: dict | bytes
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: Equipment
    """
    if connexion.request.is_json:
        equipment = EquipmentUpdate.from_dict(connexion.request.get_json())

    qEquipment = application_map.Equipment
    qEquipmentInfo = info_map.Equipment
    qTower = application_map.Tower
    qProcess = application_map.Process
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404
    # find process
    q_process = q_tower.processes.filter(
        qProcess.id == process_id).one_or_none()
    if q_process is None or q_process.id != process_id:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404

    q_equipment = q_process.equipment.filter(
        qEquipment.id == equipment_id).one_or_none()
    if q_equipment is None or q_equipment.id != equipment_id:
        error = Error('Equipment `{}` not Found'.format(equipment_id))
        return error, 404

    q_equipment.name = equipment.name or q_equipment.name

    if equipment.resource != q_equipment.resource:
        if resource_allowed(q_equipment.type, equipment.resource):
            for q_link in q_equipment.links:
                session.delete(q_link)
            q_equipment.resource = equipment.resource
        else:
            return Error('Invalid resource for this equipment.'), 400

    q_equipment.contains = equipment.contains or q_equipment.resource
    q_equipment.last_updated = equipment.last_updated or q_equipment.last_updated
    q_equipment.online = equipment.online or q_equipment.online
    session.commit()
    equipment = Equipment(id=q_equipment.id,
                          type=q_equipment.type,
                          name=q_equipment.name,
                          resource=q_equipment.resource,
                          contains=q_equipment.contains,
                          last_updated=q_equipment.last_updated,
                          online=q_equipment.online,
                          inputs=[
                              Link(source=l.source, material=l.resource)
                              for l in q_equipment.inputs
                          ],
                          outputs=[
                              Link(target=l.target, material=l.resource)
                              for l in q_equipment.outputs
                          ])

    return equipment, 200
Exemple #20
0
def towers_tower_id_processes_process_id_equipment_post(
        tower_id, process_id, equipment, api_key):
    """
    towers_tower_id_processes_process_id_equipment_post
    
    :param tower_id: Tower Id number to look under.
    :type tower_id: int
    :param process_id: Process Id number to look under.
    :type process_id: int
    :param equipment: 
    :type equipment: dict | bytes
    :param api_key: Operation Access Key
    :type api_key: str

    :rtype: Equipment
    """
    if connexion.request.is_json:
        equipment = Equipment.from_dict(connexion.request.get_json())

    try:
        # check if equipment type is valid and set the default name
        info_session = info_map.Session()
        qEquipmentInfo = info_map.Equipment
        default_name = info_session.query(qEquipmentInfo).filter(
            qEquipmentInfo.type == equipment.type).one().name
    except NoResultFound:
        error = Error('Equipment of type `{}` not valid.'.format(
            equipment.type))
        return error, 400

    qEquipment = application_map.Equipment

    qTower = application_map.Tower
    qProcess = application_map.Process
    session = application_map.Session()

    # find the tower
    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404

    q_process = q_tower.processes.filter(
        qProcess.id == process_id).one_or_none()
    if q_process is None or q_process.id != process_id:
        error = Error('Process `{}` not Found'.format(process_id))
        return error, 404

    # validate resource
    if equipment.resource is not None:
        try:
            if not resource_allowed(equipment.type, equipment.resource):
                error = Error(
                    'Resource `{}` not allowed in equipment of type `{}`.'.
                    format(equipment.resource, equipment.type))
                return error, 400
        except EquipmentNotFound as e:
            error = Error(message=str(e))
            return error, 400
        except ResourceNotFound as e:
            error = Error(message=str(e))
            return error, 400

    # set defaults if values not included
    equipment.name = equipment.name or default_name
    equipment.contains = equipment.contains or 0
    equipment.online = equipment.online or False
    equipment.last_updated = int(time.time())
    equipment.inputs = []
    equipment.outputs = []

    q_equipment = qEquipment(last_updated=equipment.last_updated,
                             resource=equipment.resource,
                             contains=equipment.contains,
                             type=equipment.type,
                             name=equipment.name,
                             online=equipment.online)

    q_process.equipment.append(q_equipment)
    session.commit()
    q_equipment.id += random.randint(
        0, 49)  # add some uncertainty so that id is not directly count
    equipment.id = q_equipment.id
    session.commit()

    return equipment, 200
Exemple #21
0
def towers_tower_id_patch(tower_id, api_key, tower_update=None):
    """
    towers_tower_id_patch
    
    :param tower_id: Id number of the tower to be deleted.
    :type tower_id: int
    :param api_key: Operation Access Key
    :type api_key: str
    :param tower_update: Details to update tower with.
    :type tower_update: dict | bytes

    :rtype: TowerDetails
    """
    if connexion.request.is_json:
        tower_update = TowerDetails.from_dict(connexion.request.get_json())

    qTower = application_map.Tower
    session = application_map.Session()

    q_tower = session.query(qTower).filter(qTower.id == tower_id).one_or_none()
    if q_tower is None or q_tower.op_id != api_key.operation_id:
        error = Error('Tower `{}` not Found'.format(tower_id))
        return error, 404
    else:
        if tower_update.type is not None:
            q_tower.type = tower_update.type
        if tower_update.system is not None:
            q_tower.system = tower_update.system
        if tower_update.planet is not None:
            q_tower.planet = tower_update.planet
        if tower_update.moon is not None:
            q_tower.moon = tower_update.moon
        if tower_update.cycles_at is not None:
            q_tower.cycles_at = tower_update.cycles_at
        if tower_update.fuel_count is not None:
            q_tower.fuel_count = tower_update.fuel_count
        if tower_update.fuel_last_update is not None:
            q_tower.fuel_last_update = tower_update.fuel_last_update
        if tower_update.online is not None:
            q_tower.online = tower_update.online
        if tower_update.sov is not None:
            q_tower.sov = tower_update.sov
        if tower_update.name is not None:
            q_tower.name = tower_update.name
        if tower_update.stront_count is not None:
            q_tower.stront_count = tower_update.stront_count

        tower_details = TowerDetails(id=q_tower.id,
                                     type=q_tower.type,
                                     system=q_tower.system,
                                     planet=q_tower.planet,
                                     moon=q_tower.moon,
                                     name=q_tower.name,
                                     cycles_at=q_tower.cycles_at,
                                     stront_count=q_tower.stront_count,
                                     fuel_count=q_tower.fuel_count,
                                     fuel_last_update=q_tower.fuel_last_update,
                                     online=q_tower.online,
                                     sov=q_tower.sov,
                                     processes=[])

        session.commit()

        return tower_details, 200