Package: py4envi
Py4EnviPy4Envi is a python library developed at IMGW-PIB that allows for easy and efficient programatic access to sat4envi resources.https://dane.sat4envi.imgw.pl/Tested for Python >= 3.7.It also provides a simple CLI tool to explore and obtain those resources without writing code.See below for examples on both use-cases.topinstallationCLIcodeInstallationFromPyPI:$pipinstallpy4enviFrom the source code (in the main directory):$python-mpipinstall.DocsSeeOpenAPI docsfolder for openapi specification.AuthenticationThe tool supports.netrcfile for automatically reading credentials if you want.
It's contents should look like this:machine dane.sat4envi.imgw.pl
login email@email.com
password some-fake-passwordOtherwise you can just provide email and password (or just token) directly. See examples below.Exemplary usage (cli)The most important thing about CLI is... help ;) show it by executing-hand any level of the tool (any subcommand etc.).It is always available and varies for different levels of this tool.
Be sure to check it very often and investigate available arguments and their order (order is important here and can be a little tricky so be sure to double check it in the help).jqtool is highly recommended to parse large json responses.# you can omit specifying email and password# they will be read from netrc automatically# you can also specify email and pwd explicitly for every command listed below like so:$py4envi-eexample@example.com-p"fake password"<otherarguments># obtained token is cached as a temporary file# if for some reason token gets out-of-date but your temp files were not cleaned# you can force getting a new token as below$py4envi-eexample@example.com-p"fake password"--new-token<otherarguments># let's query API for all available products# this returns a dataframe$py4enviproducts# a convinience param is avaiable to return json, this can be later piped to for example `jq` and used in scripts:$py4envi--jsonproducts# this is also a good example of how important is the ordering of arguments. `--json` provided at the very end won't work!# count a number of specific artifacts of a product in the specified geometry (geojson file)# filtered by cloud cover (there are many parameters to pass here, see help or OpenAPI docs)$py4envisearch--product-typeSentinel-2-L2A--footprint./tests/geojson.json--cloud-cover30.1--count# omit `---count` to return all results (again, dataframe or json, depending on the flag)$py4envi--jsonsearch--product-typeSentinel-2-L2A--footprint./tests/geojson.json--cloud-cover30.1# download a specific artifact knowing its name and id$py4envi-nproduct_archiveartifact-i6675430# specify different directory$py4envidownload-nproduct_archive-d/tmpartifact-i6675430# one can also execute download on 'ith' result of search# the same arguments as for search are available, but again, check the help# here we explicitly download the first result (this is also the default)$py4envidownload-nquicklooksearch--product-typeSentinel-2-L2A--cloud-cover30.1# interrupted download can be resumed by just calling the same command once more# if you with to overwrite the previous download, just pass `--overwrite` flag (see help)Exemplary usage (code)frompy4enviimportproducts,scenes,search,token# you can omit specifying email and password (don't pass them to functions or set them as None)# they will be read from netrc automatically# you can also specify email and pwd explicitlyemail="example@example.com"pwd="fake password"# request token to use during this sessiontkn=token.get_or_request_token(email,pwd)# token is cached as a temporary file# if for some reason token gets out-of-date but your temp files were not cleaned# you can force getting a new token as below#tkn = token.get_or_request_token(email, pwd, force=True)# let's query API for all available products# this returns a dataframeprds=products.get_products(tkn)print("products:")print(prds)# let's define some geometry (geoJSON) to work withgjs={"type":"Polygon","coordinates":[[[17.925996780395508,51.42511600068021],[17.945308685302734,51.42153011340418],[17.932262420654297,51.43180533674875],[17.92170524597168,51.4291832337135],[17.925996780395508,51.42511600068021],]],}# count a number of specific artifacts of a product in the specified geometry# filtered by cloud cover (there are many parameters to pass here, see function definition or OpenAPI docs)# return value is an integercount=search.count_artifacts(tkn,"Sentinel-2-L2A",cloud_cover=30.1,footprint=gjs)print("count:")print(count)# search for specific artifacts that satisfy other predicates# and limit the number of results to 5# this returns a geodataframesrch=search.search_artifacts(tkn,"Sentinel-2-L2A",limit=5,ingestion_from=datetime.now()-timedelta(days=60),)print("search results:")print(srch)# get a specific artifact knowing its id and name# this returns a scene artifact classscene=scenes.get_scene_artifact(tkn,6675430,"product_archive")print("scene")print(scene)# now we can download that scene artifact to the current directory# this method returns the path to the downloaded filedownloaded=scenes.download_scene_artifact(scene,Path("."))print(downloaded)# interrupted download can be resumed by just calling the same function once more# if you with to overwrite the previous download, just pass 'overwrite' flag_=scenes.download_scene_artifact(scene,Path("."),overwrite=True)Miscsat4envi_fixed_spec.jsoncontains modifies OpenAPI schema that includes datatypes forsearchendpoint