Ejemplo n.º 1
0
Archivo: pod.py Proyecto: jina-ai/jinad
async def _create_via_flow(pod_arguments: Dict):
    """
    This is used to create a remote MutablePod which gets triggered by a Flow context

    > Shouldn't be created with manual trigger

    Args: pod_arguments (Dict)

        {
            'head': PodModel,
            'tail': PodModel,
            'peas': [PodModel]
        }


    """
    pod_arguments = flowpod_to_namespace(args=pod_arguments)

    with pod_store._session():
        try:
            pod_id = pod_store._create(pod_arguments=pod_arguments)
        except PodStartException as e:
            raise HTTPException(
                status_code=404,
                detail=f'Pod couldn\'t get started:  {repr(e)}')
        except Exception as e:
            logger.error(f'Got an error while creating a pod {repr(e)}')
            raise HTTPException(status_code=404,
                                detail=f'Something went wrong')
    return {
        'status_code': status.HTTP_200_OK,
        'pod_id': pod_id,
        'status': 'started'
    }
Ejemplo n.º 2
0
async def _fetch(
    flow_id: uuid.UUID,
    yaml_only: bool = False
):
    """
    Get Flow information using `flow_id`.

    Following details are sent:
    - Flow YAML
    - Gateway host
    - Gateway port
    """
    try:
        with flow_store._session():
            host, port_expose, yaml_spec = flow_store._get(flow_id=flow_id)

        if yaml_only:
            return Response(content=yaml_spec,
                            media_type='application/yaml')

        return {
            'status_code': status.HTTP_200_OK,
            'yaml': yaml_spec,
            'host': host,
            'port': port_expose
        }
    except KeyError:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f'Flow ID {flow_id} not found! Please create a new Flow')
Ejemplo n.º 3
0
Archivo: pod.py Proyecto: jina-ai/jinad
async def _delete(pod_id: uuid.UUID):
    """Close Pod context
    """
    with pod_store._session():
        try:
            pod_store._delete(pod_id=pod_id)
            return {'status_code': status.HTTP_200_OK}
        except KeyError:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail=f'Pod ID {pod_id} not found! Please create a new Pod')
Ejemplo n.º 4
0
Archivo: pod.py Proyecto: jina-ai/jinad
async def _create_independent(pod_arguments: PodModel):
    """
    This is used to create an independent remote MutablePod which stays out of Flow context
    """
    pod_arguments = basepod_to_namespace(args=pod_arguments)

    with pod_store._session():
        try:
            pod_id = pod_store._create(pod_arguments=pod_arguments)
        except PodStartException as e:
            raise HTTPException(
                status_code=404,
                detail=f'Pod couldn\'t get started:  {repr(e)}')
        except Exception as e:
            logger.error(f'Got an error while creating a pod {repr(e)}')
            raise HTTPException(status_code=404,
                                detail=f'Something went wrong')
    return {
        'status_code': status.HTTP_200_OK,
        'pod_id': pod_id,
        'status': 'started'
    }
Ejemplo n.º 5
0
Archivo: pea.py Proyecto: jina-ai/jinad
async def _create(
    pea_arguments: PeaModel
):
    """
    Used to create a Pea on remote
    """
    pea_arguments = basepea_to_namespace(args=pea_arguments)

    with pea_store._session():
        try:
            pea_id = pea_store._create(pea_arguments=pea_arguments)
        except PeaStartException as e:
            raise HTTPException(status_code=404,
                                detail=f'Pea couldn\'t get started:  {repr(e)}')
        except Exception as e:
            logger.error(f'Got an error while creating a pea {repr(e)}')
            raise HTTPException(status_code=404,
                                detail=f'Something went wrong')
    return {
        'status_code': status.HTTP_200_OK,
        'pea_id': pea_id,
        'status': 'started'
    }
Ejemplo n.º 6
0
async def _websocket_logs(websocket: WebSocket,
                          log_id: uuid.UUID,
                          timeout: Optional[int] = 5,
                          exit_text: Optional[str] = 'exit'):
    """
    # TODO: Swagger doesn't support websocket based docs
    Websocket endpoint to stream logs from fluentd file

    ```
    `log_id`: uuid of the flow/pod/pea
    `timeout`: max time difference b/w successive log lines (helps in client disconnection)
    `exit_text`: exit the connection if this text is found in the message
    ```
    """
    file_path = log_config.PATH % log_id
    if not Path(file_path).is_file():
        raise HTTPException(status_code=404, detail=f'No logs found')

    await websocket.accept()
    client_host = websocket.client.host
    client_port = websocket.client.port
    logger.info(f'Client {client_host}:{client_port} got connected!')
    data = await websocket.receive_json()
    logger.debug(f'received the first message: {data}')
    line_num_from = int(data.get('from', 0))
    logs_to_be_sent = {}

    try:
        with open(file_path) as fp:
            async for line_number, line in tail(file_handler=fp,
                                                timeout=timeout):
                if line_number > line_num_from:
                    logs_to_be_sent[line_number] = line
                    logger.info(f'Sending logs {logs_to_be_sent}')
                    await websocket.send_text(json.dumps(logs_to_be_sent))
                    data = await websocket.receive_json()
                    if exit_text in data:
                        raise ClientExit
                    logs_to_be_sent = {}
    except WebSocketDisconnect:
        logger.info(f'Client {client_host}:{client_port} got disconnected!')
    except TimeoutException:
        await websocket.close()
        logger.info(f'No logs found in last {timeout} secs. Timing out!')
        logger.info(f'Closing client {client_host}:{client_port}!')
    except ClientExit:
        await websocket.close()
        logger.info('Client asked to exit!')
        logger.info(f'Closing client {client_host}:{client_port}!')
Ejemplo n.º 7
0
async def _create_from_pods(
    pods: Union[List[PodModel]] = Body(...,
                                       example=json.loads(PodModel().json()))
):
    """
    Build a Flow using a list of `PodModel`

        [
            {
                "name": "pod1",
                "uses": "_pass"
            },
            {
                "name": "pod2",
                "uses": "_pass",
                "host": "10.18.3.127",
                "port_expose": 8000
            }
        ]
    """
    with flow_store._session():
        try:
            flow_id, host, port_expose = flow_store._create(config=pods)
        except FlowCreationException:
            raise HTTPException(status_code=404,
                                detail=f'Bad pods args')
        except FlowStartException:
            raise HTTPException(status_code=404,
                                detail=f'Flow couldn\'t get started')
    return {
        'status_code': status.HTTP_200_OK,
        'flow_id': flow_id,
        'host': host,
        'port': port_expose,
        'status': 'started'
    }
Ejemplo n.º 8
0
async def _delete(
    flow_id: uuid.UUID
):
    """
    Close Flow context
    """
    with flow_store._session():
        try:
            flow_store._delete(flow_id=flow_id)
            return {
                'status_code': status.HTTP_200_OK
            }
        except KeyError:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                                detail=f'Flow ID {flow_id} not found! Please create a new Flow')
Ejemplo n.º 9
0
async def _ping(
    host: str,
    port: int
):
    """
    Ping to check if we can connect to gateway via gRPC `host:port`

    Note: Make sure Flow is running
    """
    kwargs = {'port_expose': port, 'host': host}
    _, args, _ = get_parsed_args(kwargs, set_client_cli_parser())
    client = Client(args)
    try:
        client.index(input_fn=['abc'])
        return {
            'status_code': status.HTTP_200_OK,
            'detail': 'connected'
        }
    except Exception:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f'Cannot connect to GRPC Server on {host}:{port}')
Ejemplo n.º 10
0
async def _create_from_yaml(
    yamlspec: UploadFile = File(...),
    uses_files: List[UploadFile] = File(()),
    pymodules_files: List[UploadFile] = File(())
):
    """
    Build a flow using [Flow YAML](https://docs.jina.ai/chapters/yaml/yaml.html#flow-yaml-sytanx)

    > Upload Flow yamlspec (`yamlspec`)

    > Yamls that Pods use (`uses_files`) (Optional)

    > Python modules (`pymodules_files`) that the Pods use (Optional)

    **yamlspec**:

        !Flow
        with:
            rest_api: true
            compress_hwm: 1024
        pods:
            encode:
                uses: helloworld.encoder.yml
                parallel: 2
            index:
                uses: helloworld.indexer.yml
                shards: 2
                separated_workspace: true

    **uses_files**: `helloworld.encoder.yml`

        !MyEncoder
        metas:
            name: myenc
            workspace: /tmp/blah
            py_modules: components.py
        requests:
            on:
                [IndexRequest, SearchRequest]:
                - !Blob2PngURI {}
                - !EncodeDriver {}
                - !ExcludeQL
                with:
                    fields:
                        - buffer
                        - chunks

    **uses_files**: `helloworld.indexer.yml`

        !CompoundIndexer
        components:
        - !NumpyIndexer
            with:
                index_filename: vec.gz
            metas:
                name: vecidx
                workspace: /tmp/blah
        - !BinaryPbIndexer
            with:
                index_filename: chunk.gz
            metas:
                name: chunkidx
                workspace: /tmp/blah
        metas:
            name: chunk_indexer
            workspace: /tmp/blah

    **pymodules_files**: `components.py`

        class MyEncoder(BaseImageEncoder):
            def __init__(self):
                ...

    """

    with flow_store._session():
        try:
            flow_id, host, port_expose = flow_store._create(config=yamlspec.file,
                                                            files=list(uses_files) + list(pymodules_files))
        except FlowYamlParseException:
            raise HTTPException(status_code=404,
                                detail=f'Invalid yaml file.')
        except FlowStartException as e:
            raise HTTPException(status_code=404,
                                detail=f'Flow couldn\'t get started:  {repr(e)}')

    return {
        'status_code': status.HTTP_200_OK,
        'flow_id': flow_id,
        'host': host,
        'port': port_expose,
        'status': 'started'
    }