Skip to content

Commit

Permalink
This should address comments in #432
Browse files Browse the repository at this point in the history
But most likely there will be changes to clunky code
  • Loading branch information
dariober committed Sep 18, 2024
1 parent 74a0108 commit b01ad2a
Show file tree
Hide file tree
Showing 13 changed files with 283 additions and 415 deletions.
67 changes: 0 additions & 67 deletions packages/apollo-cli/src/commands/assembly/add-file.ts

This file was deleted.

156 changes: 93 additions & 63 deletions packages/apollo-cli/src/commands/assembly/add-from-fasta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Args, Flags } from '@oclif/core'
import { ObjectId } from 'bson'

import { FileCommand } from '../../fileCommand.js'
import { submitAssembly } from '../../utils.js'
import { queryApollo, submitAssembly } from '../../utils.js'
import { Response } from 'undici'

export default class AddFasta extends FileCommand {
static description = `Add new assembly from a fasta file. The input file may be:
Expand All @@ -27,7 +28,8 @@ export default class AddFasta extends FileCommand {

static args = {
'input-file': Args.string({
description: 'Input fasta file or file id',
description:
'Input fasta file, local or remote, or id of a previously uploaded file',
required: true,
}),
}
Expand All @@ -48,7 +50,16 @@ export default class AddFasta extends FileCommand {
'not-editable': Flags.boolean({
char: 'n',
description:
"The fasta sequence is not editable. Apollo will not load it into the database and instead use the provided indexes to query it. This option assumes the fasta file is bgzip'd with `bgzip` and indexed with `samtools faidx`. Indexes should be named <my.fasta.gz>.gzi and <my.fasta.gz>.fai",
"The fasta sequence is not editable. Apollo will not load it into \
the database and instead use the provided indexes to query it. This option assumes \
the fasta file is bgzip'd with `bgzip` and indexed with `samtools faidx`. \
Indexes should be named <my.fasta.gz>.gzi and <my.fasta.gz>.fai unless options --fai and --gzi are set",
}),
fai: Flags.string({
description: 'Fasta index of the (not-editable) fasta file',
}),
gzi: Flags.string({
description: 'Gzi index of the (not-editable) fasta file',
}),
}

Expand All @@ -61,8 +72,12 @@ export default class AddFasta extends FileCommand {

const assemblyName = flags.assembly ?? path.basename(args['input-file'])

const fastaIsFileId = await isFileId(
args['input-file'],
access.address,
access.accessToken,
)
const isExternal = isValidHttpUrl(args['input-file'])
// const inputType = getInputType(args['input-file'])

let body
if (isExternal) {
Expand All @@ -79,76 +94,90 @@ export default class AddFasta extends FileCommand {
fai: flags.index,
},
}
// rec = await submitAssembly(
// access.address,
// access.accessToken,
// body,
// flags.force,
// )
} else if (flags['not-editable']) {
const gzi = `${args['input-file']}.gzi`
const fai = `${args['input-file']}.fai`
if (!fs.existsSync(gzi) || !fs.existsSync(fai)) {
this.error(
"Only bgzip'd and indexed fasta files are supported at the moment",
)
}
// Upload fasta file
const faId = await this.uploadFile(
const gzi = flags.gzi ?? `${args['input-file']}.gzi`
const fai = flags.fai ?? `${args['input-file']}.fai`

const gziIsFileId = await isFileId(
gzi,
access.address,
access.accessToken,
args['input-file'],
'text/x-fasta',
true,
)
// Upload fai index
const faiId = await this.uploadFile(
access.address,
access.accessToken,
const faiIsFileId = await isFileId(
fai,
'text/x-fasta',
false,
)
// Upload gzi index
const gziId = await this.uploadFile(
access.address,
access.accessToken,
gzi,
'text/x-fasta',
false,
)

if (!fs.existsSync(gzi) && !gziIsFileId) {
this.error(
`Only bgzip'd and indexed fasta files are supported at the moment. "${gzi}" is neither a file or a file id`,
)
}
if (!fs.existsSync(fai) && !faiIsFileId) {
this.error(
`Only bgzip'd and indexed fasta files are supported at the moment. "${fai}" is neither a file or a file id`,
)
}

const faId = fastaIsFileId
? args['input-file']
: await this.uploadFile(
access.address,
access.accessToken,
args['input-file'],
'application/x-bgzip-fasta',
true,
)

const faiId = faiIsFileId
? fai
: await this.uploadFile(
access.address,
access.accessToken,
fai,
'text/x-fai',
true,
)

const gziId = gziIsFileId
? gzi
: await this.uploadFile(
access.address,
access.accessToken,
gzi,
'application/x-gzi',
true,
)

body = {
assemblyName,
typeName: 'AddAssemblyFromFileIdChange',
typeName: 'AddAssemblyFromFileChange',
fileIds: {
fa: faId,
fai: faiId,
gzi: gziId,
},
}
} else {
if (!isExternal && !fs.existsSync(args['input-file'])) {
this.error(`File ${args['input-file']} does not exist`)
if (!isExternal && !fs.existsSync(args['input-file']) && !fastaIsFileId) {
this.error(`Input "${args['input-file']}" is not valid`)
}
const fileId = await this.uploadFile(
access.address,
access.accessToken,
args['input-file'],
'text/x-fasta',
false,
)
const fileId = fastaIsFileId
? args['input-file']
: await this.uploadFile(
access.address,
access.accessToken,
args['input-file'],
'text/x-fasta',
false,
)
body = {
assemblyName,
fileId,
fileIds: { fa: fileId },
typeName: 'AddAssemblyFromFileChange',
assembly: new ObjectId().toHexString(),
}
// rec = await submitAssembly(
// access.address,
// access.accessToken,
// body,
// flags.force,
// )
}

const rec = await submitAssembly(
Expand All @@ -171,15 +200,16 @@ function isValidHttpUrl(x: string) {
return url.protocol === 'http:' || url.protocol === 'https:'
}

// function getInputType(x: string): 'external' | 'local' | 'fileId' {
// if (isValidHttpUrl(x)) {
// return 'external'
// }
// if (fs.existsSync(x)) {
// return 'local'
// }
// if (x.length == 24) {
// return 'fileId'
// }
// throw new Error(`Invalid input: ${x}`)
// }
async function isFileId(x: string, address: string, accessToken: string) {
if (x.length != 24) {
return false
}
const files: Response = await queryApollo(address, accessToken, 'files')
const json = (await files.json()) as object[]
for (const fileDoc of json) {
if (fileDoc['_id' as keyof typeof fileDoc] === x) {
return true
}
}
return false
}
2 changes: 1 addition & 1 deletion packages/apollo-cli/src/commands/assembly/add-from-gff.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default class AddGff extends FileCommand {

const body = {
assemblyName,
fileId,
fileIds: { fa: fileId },
typeName,
assembly: new ObjectId().toHexString(),
}
Expand Down
16 changes: 8 additions & 8 deletions packages/apollo-cli/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -371,34 +371,34 @@ export const waitFor = <T>(
return promise
}

interface bodyLocalFile {
interface bodyFastaFile {
assemblyName: string
typeName: string
fileId: string
fileIds: { fa: string }
assembly: string
}
interface bodyExternalFile {
interface bodyIndexedFiles {
assemblyName: string
typeName: string
externalLocation: {
fileIds: {
fa: string
fai: string
gzi: string
}
}
interface bodyFileId {
interface bodyExternalFile {
assemblyName: string
typeName: string
fileIds: {
externalLocation: {
fa: string
fai: string
gzi: string | undefined
}
}

export async function submitAssembly(
address: string,
accessToken: string,
body: bodyLocalFile | bodyExternalFile | bodyFileId,
body: bodyFastaFile | bodyExternalFile | bodyIndexedFiles,
force: boolean,
): Promise<object> {
let assemblies = await queryApollo(address, accessToken, 'assemblies')
Expand Down
Loading

0 comments on commit b01ad2a

Please sign in to comment.