Reading a csv file on a Google drive without mapping

Hello

I am trying to read a file on Google drive without mapping it to a drive on Windows. The reasons I don’t want to map the drive are:
1- users may map to a different letter (I’m on Windows) and I don’t want to deal with different type of OS.
2- one of the subdirectory name contains square brackets ‘[’…]'.

Square brackets are poorly hadled with VS Code on Windows. I think this is related to Powershell. For instance

julia> filename = "H:\\Disques partagés\\[CQ] Rapports\\Netbox\\2023netbox_devices_2023-08-30.csv"
"H:\\Disques partagés\\[CQ] Rapports\\Netbox\\2023netbox_devices_2023-08-30.csv"

julia> isvalid(filename)
true

julia> df = CSV.read(filename, DataFrame)
ERROR: ArgumentError: "H:\Disques partagés\[CQ] Rapports\Netbox\2023netbox_devices_2023-08-30.csv" is not a valid file or doesn't exist
Stacktrace:
 [1] CSV.Context(source::CSV.Arg, header::CSV.Arg, normalizenames::CSV.Arg, datarow::CSV.Arg, skipto::CSV.Arg, footerskip::CSV.Arg, transpose::CSV.Arg, comment::CSV.Arg, ignoreemptyrows::CSV.Arg, ignoreemptylines::CSV.Arg, select::CSV.Arg, drop::CSV.Arg, limit::CSV.Arg, buffer_in_memory::CSV.Arg, threaded::CSV.Arg, ntasks::CSV.Arg, tasks::CSV.Arg, rows_to_check::CSV.Arg, lines_to_check::CSV.Arg, missingstrings::CSV.Arg, missingstring::CSV.Arg, delim::CSV.Arg, ignorerepeated::CSV.Arg, quoted::CSV.Arg, quotechar::CSV.Arg, openquotechar::CSV.Arg, closequotechar::CSV.Arg, escapechar::CSV.Arg, dateformat::CSV.Arg, dateformats::CSV.Arg, decimal::CSV.Arg, groupmark::CSV.Arg, truestrings::CSV.Arg, falsestrings::CSV.Arg, stripwhitespace::CSV.Arg, type::CSV.Arg, types::CSV.Arg, typemap::CSV.Arg, pool::CSV.Arg, downcast::CSV.Arg, lazystrings::CSV.Arg, stringtype::CSV.Arg, strict::CSV.Arg, silencewarnings::CSV.Arg, maxwarnings::CSV.Arg, debug::CSV.Arg, parsingdebug::CSV.Arg, validate::CSV.Arg, streaming::CSV.Arg)
   @ CSV C:\Users\denys\.julia\packages\CSV\OnldF\src\context.jl:314
 [2] #File#32
   @ C:\Users\denys\.julia\packages\CSV\OnldF\src\file.jl:222 [inlined]
 [3] CSV.File(source::String)
   @ CSV C:\Users\denys\.julia\packages\CSV\OnldF\src\file.jl:162
 [4] read(source::String, sink::Type; copycols::Bool, kwargs::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
   @ CSV C:\Users\denys\.julia\packages\CSV\OnldF\src\CSV.jl:117
 [5] read(source::String, sink::Type)
   @ CSV C:\Users\denys\.julia\packages\CSV\OnldF\src\CSV.jl:113
 [6] top-level scope
   @ REPL[15]:1

So the file is valid but does not exist (it does). Anyways I would rather avoid mapping drives.

I tried GoogleDrive.jl, unfortunately I can’t get it to compile

julia> using GoogleDrive
[ Info: Precompiling GoogleDrive [91feb7a0-3508-11ea-1e8e-afea2c1c9a19]
ERROR: LoadError: ArgumentError: broadcasting over dictionaries and `NamedTuple`s is reserved
Stacktrace:
 [1] broadcastable(#unused#::Base.EnvDict)
   @ Base.Broadcast .\broadcast.jl:718
 [2] broadcasted(f::Function, arg1::Base.EnvDict, arg2::Vector{String}, args::Vector{Vector{String}})
   @ Base.Broadcast .\broadcast.jl:1314
 [3] top-level scope
   @ C:\Users\denys\.julia\packages\DataDeps\43qPc\src\locations.jl:8
 [4] include(mod::Module, _path::String)
   @ Base .\Base.jl:457
 [5] include(x::String)
   @ DataDeps C:\Users\denys\.julia\packages\DataDeps\43qPc\src\DataDeps.jl:2
 [6] top-level scope
   @ C:\Users\denys\.julia\packages\DataDeps\43qPc\src\DataDeps.jl:19
 [7] include
   @ .\Base.jl:457 [inlined]
 [8] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::String)
   @ Base .\loading.jl:2045
 [9] top-level scope
   @ stdin:3
in expression starting at C:\Users\denys\.julia\packages\DataDeps\43qPc\src\locations.jl:4
in expression starting at C:\Users\denys\.julia\packages\DataDeps\43qPc\src\DataDeps.jl:2
in expression starting at stdin:3
ERROR: LoadError: Failed to precompile DataDeps [124859b0-ceae-595e-8997-d05f6a7a8dfe] to "C:\\Users\\denys\\.julia\\compiled\\v1.9\\DataDeps\\jl_346E.tmp".
Stacktrace:
  [1] error(s::String)
    @ Base .\error.jl:35
  [2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool)
    @ Base .\loading.jl:2296
  [3] compilecache
    @ .\loading.jl:2163 [inlined]
  [4] _require(pkg::Base.PkgId, env::String)
    @ Base .\loading.jl:1805
  [5] _require_prelocked(uuidkey::Base.PkgId, env::String)
    @ Base .\loading.jl:1660
  [6] macro expansion
    @ .\loading.jl:1648 [inlined]
  [7] macro expansion
    @ .\lock.jl:267 [inlined]
  [8] require(into::Module, mod::Symbol)
    @ Base .\loading.jl:1611
  [9] include
    @ .\Base.jl:457 [inlined]
 [10] include_package_for_output(pkg::Base.PkgId, input::String, depot_path::Vector{String}, dl_load_path::Vector{String}, load_path::Vector{String}, concrete_deps::Vector{Pair{Base.PkgId, UInt128}}, source::Nothing)
    @ Base .\loading.jl:2045
 [11] top-level scope
    @ stdin:3
in expression starting at C:\Users\denys\.julia\packages\GoogleDrive\Lg2PJ\src\GoogleDrive.jl:1
in expression starting at stdin:3
ERROR: Failed to precompile GoogleDrive [91feb7a0-3508-11ea-1e8e-afea2c1c9a19] to "C:\\Users\\denys\\.julia\\compiled\\v1.9\\GoogleDrive\\jl_3367.tmp".
Stacktrace:
 [1] error(s::String)
   @ Base .\error.jl:35
 [2] compilecache(pkg::Base.PkgId, path::String, internal_stderr::IO, internal_stdout::IO, keep_loaded_modules::Bool)
   @ Base .\loading.jl:2296
 [3] compilecache
   @ .\loading.jl:2163 [inlined]
 [4] _require(pkg::Base.PkgId, env::String)
   @ Base .\loading.jl:1805
 [5] _require_prelocked(uuidkey::Base.PkgId, env::String)
   @ Base .\loading.jl:1660
 [6] macro expansion
   @ .\loading.jl:1648 [inlined]
 [7] macro expansion
   @ .\lock.jl:267 [inlined]
 [8] require(into::Module, mod::Symbol)
   @ Base .\loading.jl:1611

Given the poor documentation on GoogleDrive.jl I feel that it is not maintained.

Anyone has an alternative of a fix for this?

Thanks for your help.

1 Like

Fyi, on Win11 and using VS Code, but had no problem to read a CSV file to a dataframe, which was located in a folder ...\[GQ] folder\...

That folder is mapped to a drive letter? Or are you reading directly with a url? I’d rather use the second way.

Cmd does not seem to have problems with square brackets. Powershell is another story, I need to use double backtics to do a cd (change directory). What is the terminal that you use with VS code?

with cmd:

H:\>cd "H:\Disques partagés\[CQ] Rapports\Netbox\2023"

H:\Disques partagés\[CQ] Rapports\Netbox\2023>

All fine, I’m in the right directory.

with Powershell:

PowerShell 7.3.6
PS C:\Users\denys> H:
PS H:\> cd "H:\Disques partagés\[CQ] Rapports\Netbox\2023"
Set-Location: Cannot find path 'H:\Disques partagés\[CQ] Rapports\Netbox\2023' because it does not exist.
PS H:\>
PS H:\> cd "H:\Disques partagés\``[CQ``] Rapports\Netbox\2023"
PS H:\Disques partagés\[CQ] Rapports\Netbox\2023>

If I change Powershell for cmd it may fix the problem. Yet, I don’t want drive mapping. We’re in 2023, a url should suffice.

Sorry if this is not helpful, but it was just a test on my C: drive running from VS Code the script:

using DataFrames, CSV
path = "C:\\Users\\jrafa\\OneDrive\\Julia_Code\\[GQ] JULIA\\german.csv"
df = CSV.read(path, DataFrame)

Thanks for your help anyway. I will work on the square bracket issue because I tested it with “C:” and it worked:

julia> fichier = "C:\\Users\\denys\\Documents\\temp\\[ CQ] Rapports\\netbox_devices_2023-08-30.csv"
"C:\\Users\\denys\\Documents\\temp\\[ CQ] Rapports\\netbox_devices_2023-08-30.csv"

julia> using CSV, DataFrames

julia> CSV.read(fichier, DataFrame)
3852×23 DataFrame
  Row │ name     

But I would prefer the user to go to the Goolgle sheet, copy the link of the csv file, paste it in the program and avoid disk mapping. Otherwise I’ll have to provide instruction for disk mapping and increase the chance of issues.

Ideally I’d like the following to work:

julia> fichier = "https://drive.google.com/file/d/1IumdUeodd7LZWlwNoLRSNJdK8QkXBrpa/view?usp=drive_link"
"https://drive.google.com/file/d/1IumdUeodd7LZWlwNoLRSNJdK8QkXBrpa/view?usp=drive_link"

julia> CSV.read(fichier, DataFrame)
ERROR: ArgumentError: "https://drive.google.com/file/d/1IumdUeodd7LZWlwNoLRSNJdK8QkXBrpa/view?usp=drive_link" is not a valid file or doesn't exist
Stacktrace

I’m pretty sure that square braces isn’t going to be a problem … I know you want a data frame, but try this just to see if the behavior is different?

CSV.read(filename)

Not better. As Rafael wisely notified me, working on the local C: drive works. For some reasons, mapping a Google drive is not the same.

julia> fichier = "H:\\Disques partagés\\[CQ] Rapports\\Netbox\\2023\\netbox_devices_2023-08-30.csv"
"H:\\Disques partagés\\[CQ] Rapports\\Netbox\\2023\\netbox_devices_2023-08-30.csv"

julia> CSV.open(fichier)
IOStream(<file H:\Disques partagés\[CQ] Rapports\Netbox\2023\netbox_devices_2023-08-30.csv>)

julia> 

Damn it, I can read the IOStream!!!

julia> toto = CSV.open(fichier)
julia> readline(toto)
"name,device_role,tenant,manufacturer,model_name,platform,serial,asset_tag,status,site,rack_group,rack_name,position,face,comments,contrib,contribdate,contribinstitution,contribnotes,contribprof,po,warrantydate,warrantydatemanuf"

julia> readline(toto)
"1L15-IB-1,IB switch Rack,,Mellanox,SB7890,,,,Active,ETS1,,1L15,41,Rear,,,,,,,,,"

julia> 

I would need to create a DataFrame from a loop I suppose (plan B).

Yet. I don’t want drive mapping. I want a url provided by Google.

1 Like

Does Examples · CSV.jl help tackle the problem you’re looking at?

I tried that. But without success. I have this message about closewrite (see below).

This seems to explain my issue but, to be honest, I don’t understand what I have to do.

help?> closewrite
WARNING: both IOExtras and Base export "closewrite"; uses of it in module HTTP must be qualified
search: closewrite

I can qualify closewrite as problematic. But that doesn’t help :grin:
Any advise?

julia> using HTTP, CSV

julia> http_response = HTTP.get("https://drive.google.com/file/d/1IumdUeodd7LZWlwNoLRSNJdK8QkXBrpa/view?usp=drive_link")
ERROR: UndefVarError: `closewrite` not defined
Stacktrace:
  [1] request(::Type{StreamLayer{Union{}}}, io::HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}, req::HTTP.Messages.Request, body::Vector{UInt8}; reached_redirect_limit::Bool, response_stream::Nothing, iofunction::Nothing, verbose::Int64, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ HTTP.StreamRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\StreamRequest.jl:83
  [2] request(::Type{ConnectionPoolLayer{StreamLayer{Union{}}}}, url::HTTP.URIs.URI, req::HTTP.Messages.Request, body::Vector{UInt8}; proxy::Nothing, socket_type::Type, reuse_limit::Int64, kw::Base.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}})
    @ HTTP.ConnectionRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\ConnectionRequest.jl:96
  [3] request(::Type{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}, ::HTTP.URIs.URI, ::Vararg{Any}; kw::Base.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}})
    @ HTTP.ExceptionRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\ExceptionRequest.jl:19
  [4] (::Base.var"#90#92"{Base.var"#90#91#93"{ExponentialBackOff, HTTP.RetryRequest.var"#2#3"{Bool, HTTP.Messages.Request}, typeof(HTTP.request)}})(::Type, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}})
    @ Base .\error.jl:296
  [5] #90
    @ .\error.jl:291 [inlined]
  [6] #request#1
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\RetryRequest.jl:44 [inlined]
  [7] request
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\RetryRequest.jl:27 [inlined]
  [8] request(::Type{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}; http_version::VersionNumber, target::String, parent::Nothing, iofunction::Nothing, kw::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:reached_redirect_limit,), Tuple{Bool}}})
    @ HTTP.MessageRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\MessageRequest.jl:51
  [9] request
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\MessageRequest.jl:22 [inlined]
 [10] request(::Type{BasicAuthLayer{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}; kw::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:reached_redirect_limit,), Tuple{Bool}}})
    @ HTTP.BasicAuthRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\BasicAuthRequest.jl:28
 [11] request
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\BasicAuthRequest.jl:18 [inlined]
 [12] request(::Type{RedirectLayer{BasicAuthLayer{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}; redirect_limit::Int64, forwardheaders::Bool, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ HTTP.RedirectRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\RedirectRequest.jl:24
 [13] request(::Type{RedirectLayer{BasicAuthLayer{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8})
    @ HTTP.RedirectRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\RedirectRequest.jl:18
 [14] request(method::String, url::String, h::Vector{Pair{SubString{String}, SubString{String}}}, b::Vector{UInt8}; headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}, query::Nothing, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ HTTP C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:314
 [15] request (repeats 2 times)
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:312 [inlined]
 [16] #get#14
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:391 [inlined]
 [17] get(a::String)
    @ HTTP C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:391
 [18] top-level scope
    @ REPL[22]:1

caused by: EOFError: read end of file
Stacktrace:
  [1] read_to_buffer(t::HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}, sizehint::Int64)
    @ HTTP.ConnectionPool C:\Users\denys\.julia\packages\HTTP\IAI92\src\ConnectionPool.jl:252
  [2] readuntil(t::HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}, f::Function, sizehint::Int64)
    @ HTTP.ConnectionPool C:\Users\denys\.julia\packages\HTTP\IAI92\src\ConnectionPool.jl:271
  [3] readuntil
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\ConnectionPool.jl:269 [inlined]
  [4] readheaders(io::HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}, message::HTTP.Messages.Response)
    @ HTTP.Messages C:\Users\denys\.julia\packages\HTTP\IAI92\src\Messages.jl:471
  [5] startread(http::HTTP.Streams.Stream{HTTP.Messages.Response, HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}})
    @ HTTP.Streams C:\Users\denys\.julia\packages\HTTP\IAI92\src\Streams.jl:155
  [6] macro expansion
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\StreamRequest.jl:67 [inlined]
  [7] macro expansion
    @ .\task.jl:476 [inlined]
  [8] request(::Type{StreamLayer{Union{}}}, io::HTTP.ConnectionPool.Transaction{MbedTLS.SSLContext}, req::HTTP.Messages.Request, body::Vector{UInt8}; reached_redirect_limit::Bool, response_stream::Nothing, iofunction::Nothing, verbose::Int64, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ HTTP.StreamRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\StreamRequest.jl:57
  [9] request(::Type{ConnectionPoolLayer{StreamLayer{Union{}}}}, url::HTTP.URIs.URI, req::HTTP.Messages.Request, body::Vector{UInt8}; proxy::Nothing, socket_type::Type, reuse_limit::Int64, kw::Base.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}})
    @ HTTP.ConnectionRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\ConnectionRequest.jl:96
 [10] request(::Type{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}, ::HTTP.URIs.URI, ::Vararg{Any}; kw::Base.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}})
    @ HTTP.ExceptionRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\ExceptionRequest.jl:19
 [11] (::Base.var"#90#92"{Base.var"#90#91#93"{ExponentialBackOff, HTTP.RetryRequest.var"#2#3"{Bool, HTTP.Messages.Request}, typeof(HTTP.request)}})(::Type, ::Vararg{Any}; kwargs::Base.Pairs{Symbol, Union{Nothing, Bool}, Tuple{Symbol, Symbol}, NamedTuple{(:iofunction, :reached_redirect_limit), Tuple{Nothing, Bool}}})
    @ Base .\error.jl:296
 [12] #90
    @ .\error.jl:291 [inlined]
 [13] #request#1
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\RetryRequest.jl:44 [inlined]
 [14] request
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\RetryRequest.jl:27 [inlined]
 [15] request(::Type{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}; http_version::VersionNumber, target::String, parent::Nothing, iofunction::Nothing, kw::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:reached_redirect_limit,), Tuple{Bool}}})
    @ HTTP.MessageRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\MessageRequest.jl:51
 [16] request
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\MessageRequest.jl:22 [inlined]
 [17] request(::Type{BasicAuthLayer{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}; kw::Base.Pairs{Symbol, Bool, Tuple{Symbol}, NamedTuple{(:reached_redirect_limit,), Tuple{Bool}}})
    @ HTTP.BasicAuthRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\BasicAuthRequest.jl:28
 [18] request
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\BasicAuthRequest.jl:18 [inlined]
 [19] request(::Type{RedirectLayer{BasicAuthLayer{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}; redirect_limit::Int64, forwardheaders::Bool, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ HTTP.RedirectRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\RedirectRequest.jl:24
 [20] request(::Type{RedirectLayer{BasicAuthLayer{MessageLayer{RetryLayer{ExceptionLayer{ConnectionPoolLayer{StreamLayer{Union{}}}}}}}}}, method::String, url::HTTP.URIs.URI, headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8})
    @ HTTP.RedirectRequest C:\Users\denys\.julia\packages\HTTP\IAI92\src\RedirectRequest.jl:18
 [21] request(method::String, url::String, h::Vector{Pair{SubString{String}, SubString{String}}}, b::Vector{UInt8}; headers::Vector{Pair{SubString{String}, SubString{String}}}, body::Vector{UInt8}, query::Nothing, kw::Base.Pairs{Symbol, Union{}, Tuple{}, NamedTuple{(), Tuple{}}})
    @ HTTP C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:314
 [22] request (repeats 2 times)
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:312 [inlined]
 [23] #get#14
    @ C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:391 [inlined]
 [24] get(a::String)
    @ HTTP C:\Users\denys\.julia\packages\HTTP\IAI92\src\HTTP.jl:391
 [25] top-level scope
    @ REPL[22]:1

julia> 
1 Like

What exactly do you want to check with this function?
Docs say:

isvalid(value) → Bool

Return true if the given value is valid for its type, which currently can be either AbstractChar or String or SubString{String}.

So it just checks that filename is a valid string. Try isfile(filename) to check if there’s a file with this name.

1 Like

ooups!. I did use isfile() previously. I mistyped in my request for help.

julia> isfile("H:\\Disques partagés\\[CQ] Rapports\\Netbox\\2023\\netbox_devices_2023-08-30.csv")
true

But as previously mentionned, I would like to avoid using mapped drives.

I can also read the data once converted into a Googlesheet. But again, I want to avoid telling my users to perform that convertion before runnning the program. A right -click on the file with “copy link” an a paste to my prompt for the file name would be better.

WARNING: both IOExtras and Base export "closewrite"; uses of it in module HTTP must be qualified
search: closewrite

Qualify in this context means that one has to tell Julia which version of closewrite it should call, e.g.

Base.closewrite(...)
# or
IOExtras.closewrite(...)

But it appears that the error is coming from inside HTTP.jl and so it might not be your fault.

1 Like

That’s what I understood. But given that the help specifically mention this, I suppose that it is known and there is a trick I don’t know. With either export or using can I tell HTTP.jl to use the proper function?

With either export or using can I tell HTTP.jl to use the proper function?

I fear not, unless you locally dev HTTP and fix the problem directly in there.

I’m sure you have tried something like this, but for completeness, I will ask: have you tried reading the stream directly from the URL as mentioned here?

f = CSV.Rows(HTTP.get(url).body)

I don’t have much experience with the CSV package in Julia, or dataframes in general - so - appologies if this is a naïve suggestion.

Same result.

julia> f = CSV.Rows(HTTP.get("https://docs.google.com/spreadsheets/d/19AQ6cSu2GVEkuEHaf18DiobpS3glf3MpOCo2w9XDP6A/edit?usp=drive_link").body)
ERROR: UndefVarError: `closewrite` not defined
Stacktrace:
...

Ah - now it really looks like a problem in a package!

Can you do a using Pkg; Pkg.status()? I suspect you might have a package blocking you from having the latest version of HTTP.jl.

Also, you can’t naively just load the CSV from the site. That URL requires you to pass the cookies/auth for Google Sheets to have the CSV.

1 Like

I did have a version issue yesterday. But I solved it. I had to remove GoogleSheets first before being allowed to upgrade. See below.

Upgrading to the latest version of HTTP.jl “partially” resolved the problem. Instead of getting twice the message that closewrite did not exist I got it only once. Seems like they are working on it!

(@v1.9) pkg> status
Status `C:\Users\denys\.julia\environments\v1.9\Project.toml`
  [336ed68f] CSV v0.10.11
  [3da002f7] ColorTypes v0.11.4
  [a93c6f00] DataFrames v1.6.1
  [e30172f5] Documenter v0.27.25
  [da1fdf0e] FreqTables v0.4.5
  [831f653e] GoogleSheets v2.0.2
  [cd3eb016] HTTP v1.9.14
  [1b4a561d] LegacyStrings v1.1.0
  [88034a9c] StringDistances v0.11.2

(@v1.9) pkg> status --outdated
Status `C:\Users\denys\.julia\environments\v1.9\Project.toml`

(@v1.9) pkg>