Skip to content

Commit ac0fe38

Browse files
committed
Merge branch 'master' of https://github.com/ODM2/ODM2PythonAPI
Conflicts: odm2api/ODM2/models_sqlite.py odm2api/ODM2/services/readService.py tests/test_odm2/test_createservice.py tests/test_odm2/test_readservice.py
2 parents ba5f9e9 + c7e2a0c commit ac0fe38

30 files changed

+2370
-4627
lines changed

.gitignore

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
*.py[cod]
22
*~
3-
.ipynb_checkpoints
3+
44

55
# C extensions
66
*.so
@@ -40,6 +40,9 @@ nosetests.xml
4040

4141
log
4242
*.log
43-
.idea
43+
4444

4545
.DS_Store
46+
.ipynb_checkpoints
47+
.cache
48+
.idea

.travis.yml

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
language: python
1+
git blanguage: python
22
sudo: required
33
# if the https://travis-ci.org/ODM2/ODM2PythonAPI/requests ever says: missing config
44
# validate at: http://lint.travis-ci.org/
@@ -38,17 +38,19 @@ addons:
3838
- libspatialite-dev
3939
# mariadb: '10.1'
4040
before_script:
41-
- ./scripts/mysql_setup.sh
42-
- ./scripts/postgres_setup.sh
43-
- ./scripts/freetds.sh
41+
- ./ci-helpers/mysql_setup.sh
42+
- ./ci-helpers/postgres_setup.sh
43+
- ./ci-helpers/travis/freetds.sh
44+
4445

4546
before_install:
4647
# python -m pip makes the install go into the virtualenv
47-
- python -m pip install pandas
48+
- sudo pip install --upgrade pip
49+
- sudo python -m pip install pandas
4850
- export PYMSSQL_BUILD_WITH_BUNDLED_FREETDS=1;python -m pip install pymssql
4951
# - python -m pip install mysql-python
5052
install: # now just our code
51-
- pip install git+https://github.com/ODM2/geoalchemy.git@odm2#egg=geoalchemy-0.7.3
53+
- pip install -e git+https://github.com/ODM2/geoalchemy.git@v0.7.4#egg=geoalchemy-0.7.4
5254
- pip install .
5355
- pip install -r requirements_tests.txt --allow-external pyodbc --allow-unverified pyodbc
5456
# pysqlite

Examples/Sample.py

+44-58
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,76 @@
11
__author__ = 'stephanie'
2-
import sys
3-
import os
42

53

6-
import matplotlib.pyplot as plt
7-
from matplotlib import dates
4+
5+
# import matplotlib.pyplot as plt
6+
87

98

10-
#this will be removed when we can installthe api
11-
# this_file = os.path.realpath(__file__)
12-
# directory = os.path.dirname(os.path.dirname(this_file))
13-
# print directory
14-
# sys.path.insert(0, directory)
159

1610
from odm2api.ODMconnection import dbconnection
1711
from odm2api.ODM2.services.readService import *
12+
from odm2api.ODM2.services import CreateODM2
1813
# Create a connection to the ODM2 database
1914
# ----------------------------------------
2015

2116

2217
#connect to database
23-
#createconnection (dbtype, servername, dbname, username, password)
24-
#session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm')
25-
#session_factory = dbconnection.createConnection('connection type: sqlite|mysql|mssql|postgresql', '/your/path/to/db/goes/here', 2.0)
26-
session_factory = dbconnection.createConnection('sqlite', '/Users/denversmith/Downloads/ODM2.sqlite', 2.0)
27-
# session_factory= dbconnection.createConnection('mssql')
18+
# createconnection (dbtype, servername, dbname, username, password)
19+
# session_factory = dbconnection.createConnection('connection type: sqlite|mysql|mssql|postgresql', '/your/path/to/db/goes/here', 2.0)#sqlite
20+
session_factory = dbconnection.createConnection('mysql', 'localhost', 'odm2', 'ODM', 'odm')#mysql
21+
# session_factory= dbconnection.createConnection('mssql', "(local)", "LBRODM2", "ODM", "odm")#win MSSQL
22+
# session_factory= dbconnection.createConnection('mssql', "arroyoodm2", "", "ODM", "odm")#mac/linux MSSQL
23+
# session_factory = dbconnection.createConnection('sqlite', '/Users/stephanie/DEV/ODM2/usecases/WOF_to_ODM2/ODM2.sqlite', 2.0)
2824

2925

3026

31-
#_session = session_factory.getSession()
3227

28+
#_session = session_factory.getSession()
3329
read = ReadODM2(session_factory)
30+
create =CreateODM2(session_factory)
3431

3532

3633

3734
# Run some basic sample queries.
3835
# ------------------------------
3936
# Get all of the variables from the database and print their names to the console
4037
allVars = read.getVariables()
41-
38+
print ("\n-------- Information about Variables ---------")
4239
for x in allVars:
4340
print(x.VariableCode + ": " + x.VariableNameCV)
4441

4542

4643

4744
# Get all of the people from the database
4845
allPeople = read.getPeople()
49-
46+
print ("\n-------- Information about People ---------")
5047
for x in allPeople:
5148
print(x.PersonFirstName + " " + x.PersonLastName)
5249

5350
try:
5451
print("\n-------- Information about an Affiliation ---------")
55-
allaff = read.getAllAffiliations()
52+
allaff = read.getAffiliations()
5653
for x in allaff:
5754
print(x.PersonObj.PersonFirstName + ": " + str(x.OrganizationID))
5855
except Exception as e:
5956
print("Unable to demo getAllAffiliations", e)
6057

6158
# Get all of the SamplingFeatures from the database that are Sites
6259
try:
63-
siteFeatures = read.getSamplingFeaturesByType('Site')
60+
print ("\n-------- Information about Sites ---------")
61+
siteFeatures = read.getSamplingFeatures()
62+
# siteFeatures = read.getSamplingFeatures(type='Site')
6463
numSites = len(siteFeatures)
65-
64+
print ("Successful query")
6665
for x in siteFeatures:
67-
print(x.SamplingFeatureCode + ": " + x.SamplingFeatureName)
66+
print(x.SamplingFeatureCode + ": " + x.SamplingFeatureTypeCV )
6867
except Exception as e:
6968
print("Unable to demo getSamplingFeaturesByType", e)
7069

7170

7271
# Now get the SamplingFeature object for a SamplingFeature code
7372
try:
74-
sf = read.getSamplingFeatureByCode('USU-LBR-Mendon')
73+
sf = read.getSamplingFeatures(codes=['USU-LBR-Mendon'])[0]
7574
print(sf)
7675
print("\n-------- Information about an individual SamplingFeature ---------")
7776
print("The following are some of the attributes of a SamplingFeature retrieved using getSamplingFeatureByCode(): \n")
@@ -87,20 +86,16 @@
8786
#add sampling feature
8887
print("\n------------ Create Sampling Feature --------- \n")
8988
try:
90-
from odm2api.ODM2.models import SamplingFeatures
91-
newsf = SamplingFeatures()
89+
# from odm2api.ODM2.models import SamplingFeatures
9290
session = session_factory.getSession()
93-
newsf.FeatureGeometry = "POINT(-111.946 41.718)"
94-
newsf.Elevation_m=100
95-
newsf.ElevationDatumCV=sf.ElevationDatumCV
96-
newsf.SamplingFeatureCode= "TestSF"
97-
newsf.SamplingFeatureDescription = "this is a test to add Feature Geomotry"
98-
newsf.SamplingFeatureGeotypeCV= "Point"
99-
newsf.SamplingFeatureTypeCV=sf.SamplingFeatureTypeCV
100-
newsf.SamplingFeatureUUID= sf.SamplingFeatureUUID+"2"
101-
session.add(newsf)
91+
newsf = Sites(FeatureGeometryWKT = "POINT(-111.946 41.718)", Elevation_m=100, ElevationDatumCV=sf.ElevationDatumCV,
92+
SamplingFeatureCode= "TestSF",SamplingFeatureDescription = "this is a test in sample.py",
93+
SamplingFeatureGeotypeCV= "Point", SamplingFeatureTypeCV=sf.SamplingFeatureTypeCV,SamplingFeatureUUID= sf.SamplingFeatureUUID+"2",
94+
SiteTypeCV="cave", Latitude= "100", Longitude= "-100", SpatialReferenceID= 0)
95+
96+
c=create.createSamplingFeature(newsf)
10297
#session.commit()
103-
print("new sampling feature added to database", newsf)
98+
print("new sampling feature added to database", c)
10499

105100
except Exception as e :
106101
print("error adding a sampling feature: " + str(e))
@@ -125,29 +120,29 @@
125120

126121

127122
# Now get a particular Result using a ResultID
128-
print("\n------- Example of Retrieving Attributes of a Time Series Result -------")
123+
print("\n------- Example of Retrieving Attributes of a Result -------")
129124
try:
130-
tsResult = read.getTimeSeriesResultByResultId(1)
125+
tsResult = read.getResults(ids = [1])[0]
131126
print (
132-
"The following are some of the attributes for the TimeSeriesResult retrieved using getTimeSeriesResultByResultID(): \n" +
133-
"ResultTypeCV: " + tsResult.ResultObj.ResultTypeCV + "\n" +
127+
"The following are some of the attributes for the TimeSeriesResult retrieved using getResults(ids=[1]): \n" +
128+
"ResultTypeCV: " + tsResult.ResultTypeCV + "\n" +
134129
# Get the ProcessingLevel from the TimeSeriesResult's ProcessingLevel object
135-
"ProcessingLevel: " + tsResult.ResultObj.ProcessingLevelObj.Definition + "\n" +
136-
"SampledMedium: " + tsResult.ResultObj.SampledMediumCV + "\n" +
130+
"ProcessingLevel: " + tsResult.ProcessingLevelObj.Definition + "\n" +
131+
"SampledMedium: " + tsResult.SampledMediumCV + "\n" +
137132
# Get the variable information from the TimeSeriesResult's Variable object
138-
"Variable: " + tsResult.ResultObj.VariableObj.VariableCode + ": " + tsResult.ResultObj.VariableObj.VariableNameCV + "\n"
139-
"AggregationStatistic: " + tsResult.AggregationStatisticCV + "\n" +
140-
"Elevation_m: " + str(sf.Elevation_m) + "\n" +
133+
"Variable: " + tsResult.VariableObj.VariableCode + ": " + tsResult.VariableObj.VariableNameCV + "\n"
134+
#"AggregationStatistic: " + tsResult.AggregationStatisticCV + "\n" +
135+
141136
# Get the site information by drilling down
142-
"SamplingFeature: " + tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureCode + " - " +
143-
tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName)
137+
"SamplingFeature: " + tsResult.FeatureActionObj.SamplingFeatureObj.SamplingFeatureCode + " - " +
138+
tsResult.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName)
144139
except Exception as e:
145140
print("Unable to demo Example of retrieving Attributes of a time Series Result: ", e)
146141

147142
# Get the values for a particular TimeSeriesResult
148143
print("\n-------- Example of Retrieving Time Series Result Values ---------")
149144

150-
tsValues = read.getTimeSeriesResultValuesByResultId(1) # Return type is a pandas dataframe
145+
tsValues = read.getResultValues(resultid = 1) # Return type is a pandas datafram
151146

152147
# Print a few Time Series Values to the console
153148
# tsValues.set_index('ValueDateTime', inplace=True)
@@ -159,18 +154,9 @@
159154
# Plot the time series
160155

161156
try:
162-
fig = plt.figure()
163-
ax = fig.add_subplot(111)
164-
tsValues.plot(x='ValueDateTime', y='DataValue', kind='line',
165-
title=tsResult.ResultObj.VariableObj.VariableNameCV + " at " + tsResult.ResultObj.FeatureActionObj.SamplingFeatureObj.SamplingFeatureName,
166-
ax=ax)
167-
ax.set_ylabel(tsResult.ResultObj.VariableObj.VariableNameCV + " (" + tsResult.ResultObj.UnitsObj.UnitsAbbreviation + ")")
168-
ax.set_xlabel("Date/Time")
169-
ax.xaxis.set_minor_locator(dates.MonthLocator())
170-
ax.xaxis.set_minor_formatter(dates.DateFormatter('%b'))
171-
ax.xaxis.set_major_locator(dates.YearLocator())
172-
ax.xaxis.set_major_formatter(dates.DateFormatter('\n%Y'))
173-
ax.grid(True)
157+
plt.figure()
158+
ax=tsValues.plot(x='ValueDateTime', y='DataValue')
159+
174160
plt.show()
175161
except Exception as e:
176162
print("Unable to demo plotting of tsValues: ", e)

Forms/clsDBConfig.py

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@ def __init__( self, parent ):
115115
self.btnTest.Bind( wx.EVT_BUTTON, self.OnBtnTest )
116116
self.btnSave.Bind( wx.EVT_BUTTON, self.OnBtnSave )
117117
self.btnCancel.Bind( wx.EVT_BUTTON, self.OnBtnCancel )
118+
119+
self.btnTest.SetFocus()
120+
118121

119122
def __del__( self ):
120123
pass

Forms/frmDBConfig.py

+1
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def validateInput(self, conn_dict):
7878
if self.service_manager.test_connection(conn_dict):
7979
message = "This connection is valid"
8080
wx.MessageBox(message, 'Test Connection', wx.OK)
81+
self.btn
8182
else:
8283
#TODO add error message if user cannont connect to the database ( not using VPN) but the db is still 1.1.1)
8384
if not (self.service_manager.get_db_version(conn_dict)):

README.md

+39-20
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,52 @@
11
ODM2 Python API
22
====
33

4-
A Python-based application programmer's interface for the Observations Data Model 2 (ODM2)
4+
A Python-based application programmer's interface for the [Observations Data Model 2 (ODM2)](http://odm2.org).
55

66
[List of current and planned functions included in the API](https://github.com/ODM2/ODM2PythonAPI/blob/master/doc/APIFunctionList.md)
77

8-
### Installation
8+
## Installation
99

10-
Currently the easiest and most reliable way to install the ODM2 Python API (`odm2api`) is using the [Conda package management system](http://conda.pydata.org/docs/) via either [Anaconda](https://www.continuum.io/downloads) or [Miniconda](http://conda.pydata.org/miniconda.html). To create a new `odm2api` environment, first download the conda environment file [condaenvironment_1.yml](https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/condaenvironment_1.yml). Then, on a terminal shell:
10+
The easiest and most reliable way to install the ODM2 Python API (`odm2api`) is using the [Conda package management system](http://conda.pydata.org/docs/) via either [Anaconda](https://www.continuum.io/downloads) or [Miniconda](http://conda.pydata.org/miniconda.html). To start using conda (if it's not your system default), add conda to the PATH; on MacOSX and Linux, it's something like `export PATH=$HOME/miniconda/bin:$PATH`, but the exact path may vary.
1111

12-
1. Add conda to the PATH; on MacOSX and Linux, it's something like `export PATH=$HOME/miniconda/bin:$PATH`, but the exact path may vary.
13-
2. Go to the directory where `condaenvironment_1.yml` was downloaded.
14-
3. Create a new conda environment. This command will create an environment called 'odm2api_env1':
12+
To activate a conda environment, say, "myenv":
13+
```bash
14+
activate myenv # On Windows
15+
source activate myenv # On MacOSX or Linux
16+
```
1517

16-
```bash
17-
conda env create -f condaenvironment_1.yml
18-
```
19-
4. Activate the new environment:
18+
**Note:** `odm2api` currently is only tested on Python 2.7. Some changes have been made to support Python 3.x, but they haven't been tested thoroughly.
2019

21-
```bash
22-
activate odm2api_env1 # On Windows
23-
source activate odm2api_env1 # On MacOSX or Linux
24-
```
25-
5. Install the `odm2api` package into the environment:
2620

27-
```bash
28-
pip install --process-dependency-links git+https://github.com/ODM2/ODM2PythonAPI.git
29-
```
30-
31-
### Credits
21+
### Latest release, from ODM2 anaconda.org channel
22+
23+
The [latest `odm2api` release](https://github.com/ODM2/ODM2PythonAPI/releases) is available on the [ODM2 anaconda.org channel](https://anaconda.org/odm2/odm2api) for all major OS paltforms (linux, OSX, win32/win64). To install it on an existing conda environment:
24+
```
25+
conda install -c odm2 odm2api
26+
```
27+
All dependencies are installed, including Pandas and its dependencies (numpy, etc).
28+
29+
To create a new environment "myenv" with the `odm2api` package:
30+
```
31+
conda create -n myenv -c odm2 python=2.7 odm2api
32+
```
33+
34+
### Installing the development version from the `master` branch on github
35+
36+
**Note from 4/26/2016:** These instructions may be slightly outdated. Follow these directions for installing the bleeding edge github master branch, mainly for development and testing purposes.
37+
38+
To create a new environment "myenv" with `odm2api`, first download the conda environment file [condaenvironment_1.yml](https://raw.githubusercontent.com/ODM2/ODM2PythonAPI/master/condaenvironment_1.yml). Go to the directory where `condaenvironment_1.yml` was downloaded. Then, on a terminal shell:
39+
```bash
40+
conda env create -n myenv --file py2_conda_environment.yml
41+
```
42+
Activate the new environment, then install `odm2api` into the environment:
43+
```bash
44+
activate myenv # On Windows
45+
source activate myenv # On MacOSX or Linux
46+
47+
pip install --process-dependency-links git+https://github.com/ODM2/ODM2PythonAPI.git
48+
```
49+
50+
## Credits
3251

3352
This work was supported by National Science Foundation Grants [EAR-1224638](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1224638) and [ACI-1339834](http://www.nsf.gov/awardsearch/showAward?AWD_ID=1339834). Any opinions, findings, and conclusions or recommendations expressed in this material are those of the author(s) and do not necessarily reflect the views of the National Science Foundation.

0 commit comments

Comments
 (0)